summaryrefslogtreecommitdiff
path: root/www/wiki/vendor/data-values
diff options
context:
space:
mode:
authorYaco <franco@reevo.org>2020-06-04 11:01:00 -0300
committerYaco <franco@reevo.org>2020-06-04 11:01:00 -0300
commitfc7369835258467bf97eb64f184b93691f9a9fd5 (patch)
treedaabd60089d2dd76d9f5fb416b005fbe159c799d /www/wiki/vendor/data-values
first commit
Diffstat (limited to 'www/wiki/vendor/data-values')
-rw-r--r--www/wiki/vendor/data-values/common/.gitignore12
-rw-r--r--www/wiki/vendor/data-values/common/.scrutinizer.yml13
-rw-r--r--www/wiki/vendor/data-values/common/.travis.yml12
-rw-r--r--www/wiki/vendor/data-values/common/COPYING347
-rw-r--r--www/wiki/vendor/data-values/common/Common.php18
-rw-r--r--www/wiki/vendor/data-values/common/README.md126
-rw-r--r--www/wiki/vendor/data-values/common/composer.json60
-rw-r--r--www/wiki/vendor/data-values/common/phpunit.xml.dist24
-rw-r--r--www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php147
-rw-r--r--www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php146
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php58
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php34
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php50
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php71
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php37
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php37
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php31
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php25
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php28
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php49
-rw-r--r--www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php120
-rw-r--r--www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php73
-rw-r--r--www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php91
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php59
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php59
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php73
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php90
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php94
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php83
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php55
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php75
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php63
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php55
-rw-r--r--www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php109
-rw-r--r--www/wiki/vendor/data-values/common/tests/bootstrap.php14
-rw-r--r--www/wiki/vendor/data-values/data-values/COPYING347
-rw-r--r--www/wiki/vendor/data-values/data-values/DataValues.php15
-rw-r--r--www/wiki/vendor/data-values/data-values/README.md113
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php96
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php96
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php93
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php15
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php102
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php99
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php174
-rw-r--r--www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php106
-rw-r--r--www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php24
-rw-r--r--www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php24
-rw-r--r--www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php14
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/bootstrap.php14
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php58
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php199
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php64
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php56
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php92
-rw-r--r--www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php60
-rw-r--r--www/wiki/vendor/data-values/geo/COPYING347
-rw-r--r--www/wiki/vendor/data-values/geo/README.md280
-rw-r--r--www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php53
-rw-r--r--www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php360
-rw-r--r--www/wiki/vendor/data-values/geo/src/GlobeMath.php116
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php226
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php167
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php198
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php136
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php138
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php108
-rw-r--r--www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php248
-rw-r--r--www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php220
-rw-r--r--www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php162
-rw-r--r--www/wiki/vendor/data-values/interfaces/COPYING347
-rw-r--r--www/wiki/vendor/data-values/interfaces/Interfaces.php18
-rw-r--r--www/wiki/vendor/data-values/interfaces/README.md119
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php123
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php15
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php33
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php67
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php67
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php122
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php32
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php97
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php114
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php35
-rw-r--r--www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php215
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php191
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php62
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php191
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php72
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php84
-rw-r--r--www/wiki/vendor/data-values/interfaces/tests/bootstrap.php14
-rw-r--r--www/wiki/vendor/data-values/validators/.gitignore12
-rw-r--r--www/wiki/vendor/data-values/validators/.phpcs.xml14
-rw-r--r--www/wiki/vendor/data-values/validators/.scrutinizer.yml18
-rw-r--r--www/wiki/vendor/data-values/validators/.travis.yml27
-rw-r--r--www/wiki/vendor/data-values/validators/COPYING347
-rw-r--r--www/wiki/vendor/data-values/validators/README.md84
-rw-r--r--www/wiki/vendor/data-values/validators/composer.json54
-rw-r--r--www/wiki/vendor/data-values/validators/phpunit.xml.dist25
-rw-r--r--www/wiki/vendor/data-values/validators/src/DimensionValidator.php267
-rw-r--r--www/wiki/vendor/data-values/validators/src/ListValidator.php63
-rw-r--r--www/wiki/vendor/data-values/validators/src/NullValidator.php41
-rw-r--r--www/wiki/vendor/data-values/validators/src/RangeValidator.php166
-rw-r--r--www/wiki/vendor/data-values/validators/src/StringValidator.php65
-rw-r--r--www/wiki/vendor/data-values/validators/src/TitleValidator.php63
-rw-r--r--www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php108
-rw-r--r--www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php220
-rw-r--r--www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php68
-rw-r--r--www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php99
-rw-r--r--www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php62
-rw-r--r--www/wiki/vendor/data-values/validators/tests/bootstrap.php14
110 files changed, 10893 insertions, 0 deletions
diff --git a/www/wiki/vendor/data-values/common/.gitignore b/www/wiki/vendor/data-values/common/.gitignore
new file mode 100644
index 00000000..577795cb
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/.gitignore
@@ -0,0 +1,12 @@
+*~
+*.kate-swp
+*.swp
+
+!.*
+
+.idea/
+build/
+vendor/
+
+composer.phar
+composer.lock \ No newline at end of file
diff --git a/www/wiki/vendor/data-values/common/.scrutinizer.yml b/www/wiki/vendor/data-values/common/.scrutinizer.yml
new file mode 100644
index 00000000..d6c0c6b6
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/.scrutinizer.yml
@@ -0,0 +1,13 @@
+build: true
+inherit: true
+
+tools:
+ php_code_coverage: true
+ php_code_sniffer: true
+ php_cpd: true
+ php_cs_fixer: true
+ php_loc: true
+ php_mess_detector: true
+ php_pdepend: true
+ php_analyzer: true
+ sensiolabs_security_checker: true
diff --git a/www/wiki/vendor/data-values/common/.travis.yml b/www/wiki/vendor/data-values/common/.travis.yml
new file mode 100644
index 00000000..1296abef
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/.travis.yml
@@ -0,0 +1,12 @@
+language: php
+
+php:
+ - 5.6
+ - 7
+ - hhvm-3.18
+
+before_script:
+ - travis_retry composer install --prefer-source
+
+script:
+ - composer ci
diff --git a/www/wiki/vendor/data-values/common/COPYING b/www/wiki/vendor/data-values/common/COPYING
new file mode 100644
index 00000000..ebba08a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text contained in
+said file overrides any license information contained in directories of smaller depth.
+Alternative licenses are typically used for software that is provided by external
+parties, and merely packaged with this software for convenience.
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
diff --git a/www/wiki/vendor/data-values/common/Common.php b/www/wiki/vendor/data-values/common/Common.php
new file mode 100644
index 00000000..5c84d978
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/Common.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * Entry point of the DataValues Common library.
+ *
+ * @since 0.1
+ * @codeCoverageIgnore
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+
+if ( defined( 'DATAVALUES_COMMON_VERSION' ) ) {
+ // Do not initialize more than once.
+ return 1;
+}
+
+define( 'DATAVALUES_COMMON_VERSION', '0.4.3' );
diff --git a/www/wiki/vendor/data-values/common/README.md b/www/wiki/vendor/data-values/common/README.md
new file mode 100644
index 00000000..e025348a
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/README.md
@@ -0,0 +1,126 @@
+# DataValues Common
+
+DataValues Common is a small library build on top of DataValues that provides common
+implementations of the DataValues, ValueParsers, ValueFormatters and ValueValidators interfaces.
+
+It is part of the [DataValues set of libraries](https://github.com/DataValues).
+
+[![Build Status](https://secure.travis-ci.org/DataValues/Common.png?branch=master)](http://travis-ci.org/DataValues/Common)
+[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Common/badges/coverage.png?s=728b9287ebdd13fbe15255d4d55575c5b5d47b8f)](https://scrutinizer-ci.com/g/DataValues/Common/)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Common/badges/quality-score.png?s=3195539d2e929aafaefb4bc006fb0da6c09a4d2a)](https://scrutinizer-ci.com/g/DataValues/Common/)
+
+On [Packagist](https://packagist.org/packages/data-values/common):
+[![Latest Stable Version](https://poser.pugx.org/data-values/common/version.png)](https://packagist.org/packages/data-values/common)
+[![Download count](https://poser.pugx.org/data-values/common/d/total.png)](https://packagist.org/packages/data-values/common)
+
+## Installation
+
+The recommended way to use this library is via [Composer](http://getcomposer.org/).
+
+### Composer
+
+To add this package as a local, per-project dependency to your project, simply add a
+dependency on `data-values/common` to your project's `composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a dependency on
+version 0.3 of this package:
+
+ {
+ "require": {
+ "data-values/common": "0.3.*"
+ }
+ }
+
+### Manual
+
+Get the code of this package, either via git, or some other means. Also get all dependencies.
+You can find a list of the dependencies in the "require" section of the composer.json file.
+Then take care of autoloading the classes defined in the src directory.
+
+## Tests
+
+This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these
+tests using the PHPUnit configuration file found in the root directory. The tests can also be run
+via TravisCI, as a TravisCI configuration file is also provided in the root directory.
+
+## Authors
+
+DataValues Common has been written by the Wikidata team, as [Wikimedia Germany]
+(https://wikimedia.de) employees for the [Wikidata project](https://wikidata.org/).
+
+## Release notes
+
+### 0.4.3 (2019-06-28)
+
+* Fixed typo in error message in `DispatchingValueParser`
+
+### 0.4.2 (2018-08-16)
+
+* The component can now be installed together with DataValues 2.x
+
+### 0.4.1 (2018-08-09)
+
+* Fixed version number not updated before.
+
+### 0.4.0 (2017-08-09)
+
+* Removed MediaWiki integration
+
+### 0.3.1 (2015-08-14)
+
+* The component can now be installed together with DataValues Interfaces 0.1.5
+
+### 0.3.0 (2015-08-11)
+
+* Added `DispatchingValueParser`
+* Added `StringNormalizer` interface
+* Added `NullStringNormalizer`
+* Added `StringParser`
+* Dropped deprecated constant `DataValuesCommon_VERSION`, use `DATAVALUES_COMMON_VERSION` instead
+* Dropped `ValueParserTestBase::getParserClass`
+* Dropped `ValueParserTestBase::newParserOptions`
+* Made `ValueParserTestBase::getInstance` abstract
+* Made `ValueParserTestBase::invalidInputProvider` abstract
+* Lowered visibility of all class fields to private
+
+### 0.2.3 (2014-10-09)
+
+* Introduced `FORMAT_NAME` class constants on ValueParsers in order to use them as expectedFormat
+* Changed ValueParsers to pass rawValue and expectedFormat arguments when constructing a `ParseException`
+* Installation together with DataValues 1.x is now supported
+
+### 0.2.2 (2014-04-11)
+
+* Introduced `DataValueMismatchException`
+
+### 0.2.1 (2014-03-12)
+
+* Minor code cleanup
+* Improved PHPUnit bootstrap
+
+### 0.2 (2013-12-16)
+
+* Added FloatParser (moved from data-values/number)
+* Added IntParser (moved from data-values/number)
+
+### 0.1.1 (2013-11-22)
+
+* Fixed link in the MediaWiki credits
+
+### 0.1 (2013-11-17)
+
+Initial release with these features:
+
+* Several DataValue implementations
+ * MonolingualTextValue
+ * MultilingualTextValue
+* Several ValueFormatter implementations
+ * StringFormatter
+* Several ValueParser implementations
+ * BoolParser
+ * DecimalParser
+ * NullParser
+
+## Links
+
+* [DataValues Common on Packagist](https://packagist.org/packages/data-values/common)
+* [DataValues Common on TravisCI](https://travis-ci.org/DataValues/Common)
diff --git a/www/wiki/vendor/data-values/common/composer.json b/www/wiki/vendor/data-values/common/composer.json
new file mode 100644
index 00000000..e49bdc99
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/composer.json
@@ -0,0 +1,60 @@
+{
+ "name": "data-values/common",
+ "type": "library",
+ "description": "Contains common implementations of the interfaces defined by DataValuesInterfaces",
+ "keywords": [
+ "datavalues",
+ "valueparsers",
+ "valueformatters",
+ "valuevalidators",
+ "wikidata"
+ ],
+ "homepage": "https://github.com/DataValues/Common",
+ "license": "GPL-2.0+",
+ "authors": [
+ {
+ "name": "Jeroen De Dauw",
+ "email": "jeroendedauw@gmail.com",
+ "homepage": "http://jeroendedauw.com",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.net/wikidata"
+ },
+ "require": {
+ "php": ">=5.3.0",
+ "data-values/data-values": "~2.0|~1.0|~0.1",
+ "data-values/interfaces": "~0.2.0|^0.1.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.7"
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.4.x-dev"
+ }
+ },
+ "autoload": {
+ "files" : [
+ "Common.php"
+ ],
+ "psr-4": {
+ "DataValues\\": "src/DataValues/",
+ "ValueFormatters\\": "src/ValueFormatters/",
+ "ValueParsers\\": "src/ValueParsers/"
+ },
+ "classmap": [
+ "tests/ValueParsers"
+ ]
+ },
+ "scripts": {
+ "test": [
+ "composer validate --no-interaction",
+ "phpunit --coverage-text=/dev/null"
+ ],
+ "ci": [
+ "composer test"
+ ]
+ }
+}
diff --git a/www/wiki/vendor/data-values/common/phpunit.xml.dist b/www/wiki/vendor/data-values/common/phpunit.xml.dist
new file mode 100644
index 00000000..1c6adb15
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/phpunit.xml.dist
@@ -0,0 +1,24 @@
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ bootstrap="tests/bootstrap.php"
+ cacheTokens="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ stopOnError="false"
+ stopOnFailure="false"
+ stopOnIncomplete="false"
+ stopOnSkipped="false"
+ verbose="true">
+ <testsuites>
+ <testsuite name="DataValuesCommon">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php b/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php
new file mode 100644
index 00000000..dcd3cd29
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/DataValues/MonolingualTextValue.php
@@ -0,0 +1,147 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a monolingual text value.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MonolingualTextValue extends DataValueObject {
+
+ /**
+ * @var string
+ */
+ private $text;
+
+ /**
+ * @var string
+ */
+ private $languageCode;
+
+ /**
+ * @since 0.1
+ *
+ * @param string $languageCode
+ * @param string $text
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( $languageCode, $text ) {
+ if ( !is_string( $languageCode ) ) {
+ throw new IllegalValueException( 'Can only construct MonolingualTextValue with a string language code.' );
+ }
+ elseif ( $languageCode === '' ) {
+ throw new IllegalValueException( 'Can not construct a MonolingualTextValue with an empty language code.' );
+ }
+
+ if ( !is_string( $text ) ) {
+ throw new IllegalValueException( 'Can only construct a MonolingualTextValue with a string value.' );
+ }
+
+ $this->text = $text;
+ $this->languageCode = $languageCode;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize() {
+ return serialize( array( $this->languageCode, $this->text ) );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ list( $languageCode, $text ) = unserialize( $value );
+ $this->__construct( $languageCode, $text );
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'monolingualtext';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return string
+ */
+ public function getSortKey() {
+ // TODO: we might want to re-think this key. Perhaps the language should simply be omitted.
+ return $this->languageCode . $this->text;
+ }
+
+ /**
+ * @see DataValue::getValue
+ *
+ * @return MonolingualTextValue
+ */
+ public function getValue() {
+ return $this;
+ }
+
+ /**
+ * Returns the text.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * Returns the language code.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getLanguageCode() {
+ return $this->languageCode;
+ }
+
+ /**
+ * @see DataValue::getArrayValue
+ *
+ * @return string[]
+ */
+ public function getArrayValue() {
+ return array(
+ 'text' => $this->text,
+ 'language' => $this->languageCode,
+ );
+ }
+
+ /**
+ * Constructs a new instance of the DataValue from the provided data.
+ * This can round-trip with @see getArrayValue
+ *
+ * @since 0.1
+ *
+ * @param string[] $data
+ *
+ * @return MonolingualTextValue
+ * @throws IllegalValueException
+ */
+ public static function newFromArray( $data ) {
+ self::requireArrayFields( $data, array( 'language', 'text' ) );
+
+ return new static( $data['language'], $data['text'] );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php b/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php
new file mode 100644
index 00000000..97e3bbe6
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/DataValues/MultilingualTextValue.php
@@ -0,0 +1,146 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a multilingual text value.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MultilingualTextValue extends DataValueObject {
+
+ /**
+ * Array with language codes pointing to their associated texts.
+ *
+ * @var MonolingualTextValue[]
+ */
+ private $texts = array();
+
+ /**
+ * @since 0.1
+ *
+ * @param MonolingualTextValue[] $monolingualValues
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( array $monolingualValues ) {
+ foreach ( $monolingualValues as $monolingualValue ) {
+ if ( !( $monolingualValue instanceof MonolingualTextValue ) ) {
+ throw new IllegalValueException( 'Can only construct MultilingualTextValue from MonolingualTextValue objects' );
+ }
+
+ $languageCode = $monolingualValue->getLanguageCode();
+
+ if ( array_key_exists( $languageCode, $this->texts ) ) {
+ throw new IllegalValueException( 'Can only add a single MonolingualTextValue per language to a MultilingualTextValue' );
+ }
+
+ $this->texts[$languageCode] = $monolingualValue;
+ }
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize() {
+ return serialize( $this->texts );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ $this->__construct( unserialize( $value ) );
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'multilingualtext';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return string|float|int
+ */
+ public function getSortKey() {
+ return empty( $this->texts ) ? '' : reset( $this->texts )->getSortKey();
+ }
+
+ /**
+ * Returns the texts as an array of monolingual text values.
+ *
+ * @since 0.1
+ *
+ * @return MonolingualTextValue[]
+ */
+ public function getTexts() {
+ return $this->texts;
+ }
+
+ /**
+ * Returns the multilingual text value
+ * @see DataValue::getValue
+ *
+ * @return MultilingualTextValue
+ */
+ public function getValue() {
+ return $this;
+ }
+
+ /**
+ * @see DataValue::getArrayValue
+ *
+ * @return mixed
+ */
+ public function getArrayValue() {
+ $values = array();
+
+ /**
+ * @var MonolingualTextValue $text
+ */
+ foreach ( $this->texts as $text ) {
+ $values[] = $text->getArrayValue();
+ }
+
+ return $values;
+ }
+
+ /**
+ * Constructs a new instance of the DataValue from the provided data.
+ * This can round-trip with
+ * @see getArrayValue
+ *
+ * @since 0.1
+ *
+ * @param mixed $data
+ *
+ * @throws IllegalValueException if $data is not an array.
+ * @return MultilingualTextValue
+ */
+ public static function newFromArray( $data ) {
+ if ( !is_array( $data ) ) {
+ throw new IllegalValueException( "array expected" );
+ }
+
+ $values = array();
+
+ foreach ( $data as $monolingualValue ) {
+ $values[] = MonolingualTextValue::newFromArray( $monolingualValue );
+ }
+
+ return new static( $values );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php b/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php
new file mode 100644
index 00000000..a07825ea
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace ValueFormatters\Exceptions;
+
+use Exception;
+use ValueFormatters\FormattingException;
+
+/**
+ * @since 0.2.1
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+class MismatchingDataValueTypeException extends FormattingException {
+
+ /**
+ * @var string
+ */
+ private $expectedValueType;
+
+ /**
+ * @var string
+ */
+ private $dataValueType;
+
+ /**
+ * @param string $expectedValueType
+ * @param string $dataValueType
+ * @param string $message
+ * @param Exception $previous
+ */
+ public function __construct( $expectedValueType, $dataValueType, $message = '',
+ Exception $previous = null
+ ) {
+ $this->expectedValueType = $expectedValueType;
+ $this->dataValueType = $dataValueType;
+
+ $message = '$dataValueType "' . $dataValueType . '" does not match $expectedValueType "'
+ . $expectedValueType . '": $message';
+
+ parent::__construct( $message, 0, $previous );
+ }
+
+ /**
+ * @return string
+ */
+ public function getExpectedValueType() {
+ return $this->expectedValueType;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDataValueType() {
+ return $this->dataValueType;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php b/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php
new file mode 100644
index 00000000..acb6b504
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueFormatters/StringFormatter.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace ValueFormatters;
+
+use DataValues\StringValue;
+use InvalidArgumentException;
+
+/**
+ * Formatter for string values
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+class StringFormatter extends ValueFormatterBase {
+
+ /**
+ * @see ValueFormatter::format
+ *
+ * @param StringValue $dataValue
+ *
+ * @throws InvalidArgumentException
+ * @return string Text
+ */
+ public function format( $dataValue ) {
+ if ( !( $dataValue instanceof StringValue ) ) {
+ throw new InvalidArgumentException( 'Data value type mismatch. Expected a StringValue.' );
+ }
+
+ return $dataValue->getValue();
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php
new file mode 100644
index 00000000..fb73aa25
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/BoolParser.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\BooleanValue;
+
+/**
+ * ValueParser that parses the string representation of a boolean.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class BoolParser extends StringValueParser {
+
+ const FORMAT_NAME = 'bool';
+
+ private static $values = array(
+ 'yes' => true,
+ 'on' => true,
+ '1' => true,
+ 'true' => true,
+ 'no' => false,
+ 'off' => false,
+ '0' => false,
+ 'false' => false,
+ );
+
+ /**
+ * @see StringValueParser::stringParse
+ *
+ * @param string $value
+ *
+ * @return BooleanValue
+ * @throws ParseException
+ */
+ protected function stringParse( $value ) {
+ $rawValue = $value;
+
+ $value = strtolower( $value );
+
+ if ( array_key_exists( $value, self::$values ) ) {
+ return new BooleanValue( self::$values[$value] );
+ }
+
+ throw new ParseException( 'Not a boolean', $rawValue, self::FORMAT_NAME );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php
new file mode 100644
index 00000000..5146a3e6
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/DispatchingValueParser.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace ValueParsers;
+
+use InvalidArgumentException;
+
+/**
+ * A generic value parser that forwards parsing to a list of other value parsers and returns the
+ * result of the first parse attempt that succeeded.
+ *
+ * @since 0.3
+ *
+ * @licence GNU GPL v2+
+ * @author Thiemo Mättig
+ */
+class DispatchingValueParser implements ValueParser {
+
+ /**
+ * @var ValueParser[]
+ */
+ private $parsers;
+
+ /**
+ * @see ParseException::getExpectedFormat
+ *
+ * @var string
+ */
+ private $format;
+
+ /**
+ * @param ValueParser[] $parsers
+ * @param string $format An identifier describing the expected format of the values to parse.
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct( array $parsers, $format ) {
+ if ( empty( $parsers ) ) {
+ throw new InvalidArgumentException( '$parsers must be a non-empty array' );
+ }
+
+ if ( !is_string( $format ) || $format === '' ) {
+ throw new InvalidArgumentException( '$format must be a non-empty string' );
+ }
+
+ $this->parsers = $parsers;
+ $this->format = $format;
+ }
+
+ /**
+ * @param mixed $value
+ *
+ * @throws ParseException
+ * @return mixed
+ */
+ public function parse( $value ) {
+ foreach ( $this->parsers as $parser ) {
+ try {
+ return $parser->parse( $value );
+ } catch ( ParseException $ex ) {
+ continue;
+ }
+ }
+
+ throw new ParseException(
+ 'The value is not recognized by the configured parsers',
+ $value,
+ $this->format
+ );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php
new file mode 100644
index 00000000..9472fa6f
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/FloatParser.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\NumberValue;
+
+/**
+ * ValueParser that parses the string representation of a float.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class FloatParser extends StringValueParser {
+
+ const FORMAT_NAME = 'float';
+
+ /**
+ * @see StringValueParser::stringParse
+ *
+ * TODO: add options for different group and decimal separators.
+ *
+ * @param string $value
+ *
+ * @return NumberValue
+ * @throws ParseException
+ */
+ protected function stringParse( $value ) {
+ if ( preg_match( '/^(-)?\d+((\.|,)\d+)?$/', $value ) ) {
+ return new NumberValue( (float)$value );
+ }
+
+ throw new ParseException( 'Not a float', $value, self::FORMAT_NAME );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php
new file mode 100644
index 00000000..8ca2f0fe
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/IntParser.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\NumberValue;
+
+/**
+ * ValueParser that parses the string representation of an integer.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class IntParser extends StringValueParser {
+
+ const FORMAT_NAME = 'int';
+
+ /**
+ * @see StringValueParser::stringParse
+ *
+ * @param string $value
+ *
+ * @return NumberValue
+ * @throws ParseException
+ */
+ protected function stringParse( $value ) {
+ $positiveValue = strpos( $value, '-' ) === 0 ? substr( $value, 1 ) : $value;
+
+ if ( ctype_digit( $positiveValue ) ) {
+ return new NumberValue( (int)$value );
+ }
+
+ throw new ParseException( 'Not an integer', $value, self::FORMAT_NAME );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php
new file mode 100644
index 00000000..70ce3029
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/NullStringNormalizer.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace ValueParsers\Normalizers;
+
+use InvalidArgumentException;
+
+/**
+ * Null implementation of StringNormalizer.
+ *
+ * @since 0.3
+ *
+ * @license GPL 2+
+ * @author Daniel Kinzler
+ */
+class NullStringNormalizer implements StringNormalizer {
+
+ /**
+ * @param string $value
+ *
+ * @throws InvalidArgumentException if $value is not a string
+ * @return string the normalized value
+ */
+ public function normalize( $value ) {
+ if ( !is_string( $value ) ) {
+ throw new InvalidArgumentException( 'Parameter $value must be a string' );
+ }
+
+ return $value;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php
new file mode 100644
index 00000000..d0cfe90e
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/Normalizers/StringNormalizer.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace ValueParsers\Normalizers;
+
+use InvalidArgumentException;
+
+/**
+ * Interface for string normalization.
+ *
+ * @since 0.3
+ *
+ * @license GPL 2+
+ * @author Daniel Kinzler
+ */
+interface StringNormalizer {
+
+ /**
+ * @param string $value
+ *
+ * @throws InvalidArgumentException if $value is not a string
+ * @return string the normalized value
+ */
+ public function normalize( $value );
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php
new file mode 100644
index 00000000..de6ca580
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/NullParser.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\UnknownValue;
+
+/**
+ * Implementation of the ValueParser interface that does a null parse.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class NullParser implements ValueParser {
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param mixed $value
+ *
+ * @return UnknownValue
+ */
+ public function parse( $value ) {
+ return new UnknownValue( $value );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php
new file mode 100644
index 00000000..820446d1
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/StringParser.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace ValueParsers;
+
+use DataValues\StringValue;
+use InvalidArgumentException;
+use ValueParsers\Normalizers\NullStringNormalizer;
+use ValueParsers\Normalizers\StringNormalizer;
+
+/**
+ * Implementation of the ValueParser interface for StringValues.
+ *
+ * @since 0.3
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class StringParser implements ValueParser {
+
+ /**
+ * @var StringNormalizer
+ */
+ private $normalizer;
+
+ /**
+ * @param StringNormalizer $normalizer
+ */
+ public function __construct( StringNormalizer $normalizer = null ) {
+ $this->normalizer = $normalizer ?: new NullStringNormalizer();
+ }
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param string $value
+ *
+ * @throws InvalidArgumentException if $value is not a string
+ * @return StringValue
+ */
+ public function parse( $value ) {
+ if ( !is_string( $value ) ) {
+ throw new InvalidArgumentException( 'Parameter $value must be a string' );
+ }
+
+ $value = $this->normalizer->normalize( $value );
+ return new StringValue( $value );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php b/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php
new file mode 100644
index 00000000..0e17ac25
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/src/ValueParsers/StringValueParser.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace ValueParsers;
+
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * ValueParser that parses the string representation of something.
+ *
+ * @since 0.1
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class StringValueParser implements ValueParser {
+
+ /**
+ * @since 0.1
+ *
+ * @var ParserOptions
+ */
+ protected $options;
+
+ /**
+ * @since 0.1
+ *
+ * @param ParserOptions|null $options
+ */
+ public function __construct( ParserOptions $options = null ) {
+ $this->options = $options ?: new ParserOptions();
+
+ $this->defaultOption( ValueParser::OPT_LANG, 'en' );
+ }
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ * @throws ParseException
+ */
+ public function parse( $value ) {
+ if ( is_string( $value ) ) {
+ return $this->stringParse( $value );
+ }
+
+ throw new ParseException( 'Not a string' );
+ }
+
+ /**
+ * Parses the provided string and returns the result.
+ *
+ * @since 0.1
+ *
+ * @param string $value
+ *
+ * @return mixed
+ */
+ protected abstract function stringParse( $value );
+
+ /**
+ * @since 0.1
+ *
+ * @param ParserOptions $options
+ */
+ public function setOptions( ParserOptions $options ) {
+ $this->options = $options;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @return ParserOptions
+ */
+ public function getOptions() {
+ return $this->options;
+ }
+
+ /**
+ * Shortcut to $this->options->getOption.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws InvalidArgumentException
+ * @return mixed
+ */
+ protected final function getOption( $option ) {
+ return $this->options->getOption( $option );
+ }
+
+ /**
+ * Shortcut to $this->options->requireOption.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws RuntimeException
+ */
+ protected final function requireOption( $option ) {
+ $this->options->requireOption( $option );
+ }
+
+ /**
+ * Shortcut to $this->options->defaultOption.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $default
+ */
+ protected final function defaultOption( $option, $default ) {
+ $this->options->defaultOption( $option, $default );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php b/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php
new file mode 100644
index 00000000..5d271f4f
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/DataValues/MonolingualTextValueTest.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\MonolingualTextValue;
+
+/**
+ * @covers DataValues\MonolingualTextValue
+ *
+ * @since 0.1
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MonolingualTextValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return 'DataValues\MonolingualTextValue';
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = array();
+
+ $argLists[] = array( 'en', 'foo' );
+ $argLists[] = array( 'en', ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' );
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = array();
+
+ $argLists[] = array( 42, null );
+ $argLists[] = array( array(), null );
+ $argLists[] = array( false, null );
+ $argLists[] = array( true, null );
+ $argLists[] = array( null, null );
+ $argLists[] = array( 'en', 42 );
+ $argLists[] = array( 'en', false );
+ $argLists[] = array( 'en', array() );
+ $argLists[] = array( 'en', null );
+ $argLists[] = array( '', 'foo' );
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ * @param MonolingualTextValue $text
+ * @param array $arguments
+ */
+ public function testGetText( MonolingualTextValue $text, array $arguments ) {
+ $this->assertEquals( $arguments[1], $text->getText() );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ * @param MonolingualTextValue $text
+ * @param array $arguments
+ */
+ public function testGetLanguageCode( MonolingualTextValue $text, array $arguments ) {
+ $this->assertEquals( $arguments[0], $text->getLanguageCode() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php b/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php
new file mode 100644
index 00000000..b0cc4062
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/DataValues/MultilingualTextValueTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\MonolingualTextValue;
+use DataValues\MultilingualTextValue;
+
+/**
+ * @covers DataValues\MultilingualTextValue
+ *
+ * @since 0.1
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class MultilingualTextValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return 'DataValues\MultilingualTextValue';
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = array();
+
+ $argLists[] = array( array() );
+ $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ) ) );
+ $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), new MonolingualTextValue( 'de', 'foo' ) ) );
+ $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), new MonolingualTextValue( 'de', 'bar' ) ) );
+ $argLists[] = array( array(
+ new MonolingualTextValue( 'en', 'foo' ),
+ new MonolingualTextValue( 'de', ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' )
+ ) );
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = array();
+
+ $argLists[] = array( array( 42 ) );
+ $argLists[] = array( array( false ) );
+ $argLists[] = array( array( true ) );
+ $argLists[] = array( array( null ) );
+ $argLists[] = array( array( array() ) );
+ $argLists[] = array( array( 'foo' ) );
+
+ $argLists[] = array( array( 42 => 'foo' ) );
+ $argLists[] = array( array( '' => 'foo' ) );
+ $argLists[] = array( array( 'en' => 42 ) );
+ $argLists[] = array( array( 'en' => null ) );
+ $argLists[] = array( array( 'en' => true ) );
+ $argLists[] = array( array( 'en' => array() ) );
+ $argLists[] = array( array( 'en' => 4.2 ) );
+
+ $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), false ) );
+ $argLists[] = array( array( new MonolingualTextValue( 'en', 'foo' ), 'foobar' ) );
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ * @param MultilingualTextValue $texts
+ * @param array $arguments
+ */
+ public function testGetTexts( MultilingualTextValue $texts, array $arguments ) {
+ $actual = $texts->getTexts();
+
+ $this->assertInternalType( 'array', $actual );
+ $this->assertContainsOnlyInstancesOf( '\DataValues\MonolingualTextValue', $actual );
+ $this->assertEquals( $arguments[0], array_values( $actual ) );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ * @param MultilingualTextValue $texts
+ * @param array $arguments
+ */
+ public function testGetValue( MultilingualTextValue $texts, array $arguments ) {
+ $this->assertInstanceOf( $this->getClass(), $texts->getValue() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php b/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php
new file mode 100644
index 00000000..8a211871
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueFormatters/Exceptions/MismatchingDataValueTypeException.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace ValueFormatters\Tests\Exceptions;
+
+use ValueFormatters\Exceptions\MismatchingDataValueTypeException;
+
+/**
+ * @covers ValueFormatters\Exceptions\MismatchingDataValueTypeException
+ *
+ * @group ValueFormatters
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+class MismatchingDataValueTypeExceptionTest extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider constructorProvider
+ * @param string $expectedType
+ * @param string $actualType
+ */
+ public function testConstructorWithRequiredArguments( $expectedType, $actualType ) {
+ $exception = new MismatchingDataValueTypeException( $expectedType, $actualType );
+
+ $this->assertEquals( $actualType, $exception->getDataValueType() );
+ $this->assertEquals( $expectedType, $exception->getExpectedValueType() );
+ }
+
+ /**
+ * @dataProvider constructorProvider
+ * @param string $expectedType
+ * @param string $actualType
+ */
+ public function testConstructorWithAllArguments( $expectedType, $actualType ) {
+ $message = 'Onoez! an error!';
+ $previous = new \Exception( 'Onoez!' );
+
+ $exception = new MismatchingDataValueTypeException(
+ $expectedType,
+ $actualType,
+ $message,
+ $previous
+ );
+
+ $this->assertEquals( $actualType, $exception->getDataValueType() );
+ $this->assertEquals( $expectedType, $exception->getExpectedValueType() );
+ $this->assertContains( $message, $exception->getMessage() );
+ $this->assertEquals( $previous, $exception->getPrevious() );
+ }
+
+ public function constructorProvider() {
+ return array(
+ array( 'string', 'time' ),
+ array( 'globecoordinate', 'string' )
+ );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php b/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php
new file mode 100644
index 00000000..3aef1501
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueFormatters/StringFormatterTest.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace ValueFormatters\Test;
+
+use DataValues\StringValue;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\StringFormatter;
+
+/**
+ * @covers ValueFormatters\StringFormatter
+ *
+ * @group ValueFormatters
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Katie Filbert < aude.wiki@gmail.com >
+ */
+class StringFormatterTest extends ValueFormatterTestBase {
+
+ /**
+ * @deprecated since 0.2, just use getInstance.
+ */
+ protected function getFormatterClass() {
+ throw new \LogicException( 'Should not be called, use getInstance' );
+ }
+
+ /**
+ * @see ValueFormatterTestBase::getInstance
+ *
+ * @param FormatterOptions|null $options
+ *
+ * @return StringFormatter
+ */
+ protected function getInstance( FormatterOptions $options = null ) {
+ return new StringFormatter( $options );
+ }
+
+ /**
+ * @see ValueFormatterTestBase::validProvider
+ */
+ public function validProvider() {
+ $strings = array(
+ 'ice cream',
+ 'cake',
+ '',
+ ' a ',
+ ' ',
+ );
+
+ $argLists = array();
+
+ foreach ( $strings as $string ) {
+ $argLists[] = array( new StringValue( $string ), $string );
+ }
+
+ return $argLists;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php
new file mode 100644
index 00000000..9de03a25
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/BoolParserTest.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use DataValues\BooleanValue;
+use ValueParsers\BoolParser;
+
+/**
+ * @covers ValueParsers\BoolParser
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class BoolParserTest extends StringValueParserTest {
+
+ /**
+ * @see ValueParserTestBase::getInstance
+ *
+ * @return BoolParser
+ */
+ protected function getInstance() {
+ return new BoolParser();
+ }
+
+ /**
+ * @see ValueParserTestBase::validInputProvider
+ */
+ public function validInputProvider() {
+ $argLists = array();
+
+ $valid = array(
+ 'yes' => true,
+ 'on' => true,
+ '1' => true,
+ 'true' => true,
+ 'no' => false,
+ 'off' => false,
+ '0' => false,
+ 'false' => false,
+
+ 'YeS' => true,
+ 'ON' => true,
+ 'No' => false,
+ 'OfF' => false,
+ );
+
+ foreach ( $valid as $value => $expected ) {
+ $expected = new BooleanValue( $expected );
+ $argLists[] = array( (string)$value, $expected );
+ }
+
+ return $argLists;
+ }
+
+ public function invalidInputProvider() {
+ $argLists = parent::invalidInputProvider();
+
+ $invalid = array(
+ 'foo',
+ '2',
+ );
+
+ foreach ( $invalid as $value ) {
+ $argLists[] = array( $value );
+ }
+
+ return $argLists;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php
new file mode 100644
index 00000000..dc94e1f6
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/DispatchingValueParserTest.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use InvalidArgumentException;
+use PHPUnit_Framework_MockObject_Matcher_Invocation;
+use PHPUnit_Framework_TestCase;
+use ValueParsers\DispatchingValueParser;
+use ValueParsers\ParseException;
+use ValueParsers\ValueParser;
+
+/**
+ * @covers ValueParsers\DispatchingValueParser
+ *
+ * @group ValueParsers
+ * @group WikibaseLib
+ * @group Wikibase
+ *
+ * @licence GNU GPL v2+
+ * @author Thiemo Mättig
+ */
+class DispatchingValueParserTest extends PHPUnit_Framework_TestCase {
+
+ /**
+ * @param PHPUnit_Framework_MockObject_Matcher_Invocation $invocation
+ *
+ * @return ValueParser
+ */
+ private function getParser( PHPUnit_Framework_MockObject_Matcher_Invocation $invocation ) {
+ $mock = $this->getMockBuilder( 'ValueParsers\ValueParser' )
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $mock->expects( $invocation )
+ ->method( 'parse' )
+ ->will( $this->returnCallback( function( $value ) {
+ if ( $value === 'invalid' ) {
+ throw new ParseException( 'failed' );
+ }
+ return $value;
+ } ) );
+
+ return $mock;
+ }
+
+ /**
+ * @dataProvider invalidConstructorArgumentsProvider
+ * @expectedException InvalidArgumentException
+ */
+ public function testGivenInvalidConstructorArguments_constructorThrowsException( $parsers, $format ) {
+ new DispatchingValueParser( $parsers, $format );
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $parsers = array(
+ $this->getParser( $this->never() ),
+ );
+
+ return array(
+ array( array(), 'format' ),
+ array( $parsers, null ),
+ array( $parsers, '' ),
+ );
+ }
+
+ public function testParse() {
+ $parser = new DispatchingValueParser(
+ array(
+ $this->getParser( $this->once() ),
+ $this->getParser( $this->never() ),
+ ),
+ 'format'
+ );
+
+ $this->assertEquals( 'valid', $parser->parse( 'valid' ) );
+ }
+
+ public function testParseThrowsException() {
+ $parser = new DispatchingValueParser(
+ array(
+ $this->getParser( $this->once() ),
+ ),
+ 'format'
+ );
+
+ $this->setExpectedException( 'ValueParsers\ParseException' );
+ $parser->parse( 'invalid' );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php
new file mode 100644
index 00000000..27d35fea
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/FloatParserTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use DataValues\NumberValue;
+use ValueParsers\FloatParser;
+
+/**
+ * @covers ValueParsers\FloatParser
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ * @group FloatParserTest
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class FloatParserTest extends StringValueParserTest {
+
+ /**
+ * @see ValueParserTestBase::getInstance
+ *
+ * @return FloatParser
+ */
+ protected function getInstance() {
+ return new FloatParser();
+ }
+
+ /**
+ * @see ValueParserTestBase::validInputProvider
+ */
+ public function validInputProvider() {
+ $argLists = array();
+
+ $valid = array(
+ '0' => 0,
+ '1' => 1,
+ '42' => 42,
+ '01' => 01,
+ '9001' => 9001,
+ '-1' => -1,
+ '-42' => -42,
+
+ '0.0' => 0,
+ '1.0' => 1,
+ '4.2' => 4.2,
+ '0.1' => 0.1,
+ '90.01' => 90.01,
+ '-1.0' => -1,
+ '-4.2' => -4.2,
+ );
+
+ foreach ( $valid as $value => $expected ) {
+ // Because PHP turns them into ints/floats using black magic
+ $value = (string)$value;
+
+ // Because 1 is an int but will come out as a float
+ $expected = (float)$expected;
+
+ $expected = new NumberValue( $expected );
+ $argLists[] = array( $value, $expected );
+ }
+
+ return $argLists;
+ }
+
+ public function invalidInputProvider() {
+ $argLists = parent::invalidInputProvider();
+
+ $invalid = array(
+ 'foo',
+ '',
+ '--1',
+ '1-',
+ '1 1',
+ '1,',
+ ',1',
+ ',1,',
+ 'one',
+ '0x20',
+ '+1',
+ '1+1',
+ '1-1',
+ '1.2.3',
+ );
+
+ foreach ( $invalid as $value ) {
+ $argLists[] = array( $value );
+ }
+
+ return $argLists;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php
new file mode 100644
index 00000000..e039373d
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/IntParserTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use DataValues\NumberValue;
+use ValueParsers\IntParser;
+
+/**
+ * @covers ValueParsers\IntParser
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class IntParserTest extends StringValueParserTest {
+
+ /**
+ * @see ValueParserTestBase::getInstance
+ *
+ * @return IntParser
+ */
+ protected function getInstance() {
+ return new IntParser();
+ }
+
+ /**
+ * @see ValueParserTestBase::validInputProvider
+ */
+ public function validInputProvider() {
+ $argLists = array();
+
+ $valid = array(
+ '0' => 0,
+ '1' => 1,
+ '42' => 42,
+ '01' => 01,
+ '9001' => 9001,
+ '-1' => -1,
+ '-42' => -42,
+ );
+
+ foreach ( $valid as $value => $expected ) {
+ // Because PHP turns them into ints using black magic
+ $value = (string)$value;
+
+ $expected = new NumberValue( $expected );
+ $argLists[] = array( $value, $expected );
+ }
+
+ return $argLists;
+ }
+
+ public function invalidInputProvider() {
+ $argLists = parent::invalidInputProvider();
+
+ $invalid = array(
+ 'foo',
+ '4.2',
+ '',
+ '--1',
+ '1-',
+ '1 1',
+ '1,',
+ ',1',
+ ',1,',
+ 'one',
+ '0x20',
+ '+1',
+ '1+1',
+ '1-1',
+ '1.2.3',
+ );
+
+ foreach ( $invalid as $value ) {
+ $argLists[] = array( $value );
+ }
+
+ return $argLists;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php
new file mode 100644
index 00000000..ba528370
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/Normalizers/NullStringNormalizerTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace ValueParsers\Normalizers\Test;
+
+use DataValues\DataValue;
+use DataValues\StringValue;
+use PHPUnit_Framework_TestCase;
+use ValueParsers\Normalizers\NullStringNormalizer;
+
+/**
+ * @covers ValueParsers\Normalizers\NullStringNormalizer
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Thiemo Mättig
+ */
+class NullStringNormalizerTest extends PHPUnit_Framework_TestCase {
+
+ /**
+ * @dataProvider stringProvider
+ */
+ public function testNormalize( $value ) {
+ $normalizer = new NullStringNormalizer();
+ $this->assertSame( $value, $normalizer->normalize( $value ) );
+ }
+
+ public function stringProvider() {
+ return array(
+ array( '' ),
+ array( 'a' ),
+ array( ' a ' ),
+ );
+ }
+
+ /**
+ * @dataProvider invalidValueProvider
+ */
+ public function testNormalizeException( $value ) {
+ $normalizer = new NullStringNormalizer();
+ $this->setExpectedException( 'InvalidArgumentException' );
+ $normalizer->normalize( $value );
+ }
+
+ public function invalidValueProvider() {
+ return array(
+ array( null ),
+ array( true ),
+ array( 1 ),
+ array( new StringValue( '' ) ),
+ );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php
new file mode 100644
index 00000000..f4ad45fa
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/NullParserTest.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use DataValues\UnknownValue;
+use ValueParsers\NullParser;
+use ValueParsers\ValueParser;
+
+/**
+ * @covers ValueParsers\NullParser
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class NullParserTest extends ValueParserTestBase {
+
+ /**
+ * @see ValueParserTestBase::getInstance
+ *
+ * @return NullParser
+ */
+ protected function getInstance() {
+ return new NullParser();
+ }
+
+ /**
+ * @see ValueParserTestBase::validInputProvider
+ */
+ public function validInputProvider() {
+ $argLists = array();
+
+ $values = array(
+ '42',
+ 42,
+ false,
+ array(),
+ 'ohi there!',
+ null,
+ 4.2,
+ );
+
+ foreach ( $values as $value ) {
+ $argLists[] = array(
+ $value,
+ new UnknownValue( $value )
+ );
+ }
+
+ return $argLists;
+ }
+
+ /**
+ * @see ValueParserTestBase::invalidInputProvider
+ */
+ public function invalidInputProvider() {
+ return array(
+ array( null )
+ );
+ }
+
+ /**
+ * @see ValueParserTestBase::testParseWithInvalidInputs
+ *
+ * @dataProvider invalidInputProvider
+ * @param mixed $value
+ * @param ValueParser|null $parser
+ */
+ public function testParseWithInvalidInputs( $value, ValueParser $parser = null ) {
+ $this->markTestSkipped( 'NullParser has no invalid inputs' );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php
new file mode 100644
index 00000000..08751663
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringParserTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use DataValues\DataValue;
+use DataValues\StringValue;
+use ValueParsers\Normalizers\StringNormalizer;
+use ValueParsers\StringParser;
+
+/**
+ * @covers ValueParsers\StringParser
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Daniel Kinzler
+ */
+class StringParserTest extends \PHPUnit_Framework_TestCase {
+
+ public function provideParse() {
+ $normalizer = $this->getMock( 'ValueParsers\Normalizers\StringNormalizer' );
+ $normalizer->expects( $this->once() )
+ ->method( 'normalize' )
+ ->will( $this->returnCallback( function( $value ) {
+ return strtolower( trim( $value ) );
+ } ) );
+
+ return array(
+ 'simple' => array( 'hello world', null, new StringValue( 'hello world' ) ),
+ 'normalize' => array( ' Hello World ', $normalizer, new StringValue( 'hello world' ) ),
+ );
+ }
+
+ /**
+ * @dataProvider provideParse
+ */
+ public function testParse( $input, StringNormalizer $normalizer = null, DataValue $expected ) {
+ $parser = new StringParser( $normalizer );
+ $value = $parser->parse( $input );
+
+ $this->assertInstanceOf( 'DataValues\StringValue', $value );
+ $this->assertEquals( $expected->toArray(), $value->toArray() );
+ }
+
+ public function nonStringProvider() {
+ return array(
+ 'null' => array( null ),
+ 'array' => array( array() ),
+ 'int' => array( 7 ),
+ );
+ }
+
+ /**
+ * @dataProvider nonStringProvider
+ */
+ public function testGivenNonString_parseThrowsException( $input ) {
+ $parser = new StringParser();
+ $this->setExpectedException( 'InvalidArgumentException' );
+ $parser->parse( $input );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php
new file mode 100644
index 00000000..962de1d7
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/StringValueParserTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use ValueParsers\ParserOptions;
+use ValueParsers\StringValueParser;
+
+/**
+ * Unit test StringValueParser class.
+ *
+ * @since 0.1
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class StringValueParserTest extends ValueParserTestBase {
+
+ /**
+ * @see ValueParserTestBase::invalidInputProvider
+ *
+ * @return array[]
+ */
+ public function invalidInputProvider() {
+ return array(
+ array( true ),
+ array( false ),
+ array( null ),
+ array( 4.2 ),
+ array( array() ),
+ array( 42 ),
+ );
+ }
+
+ public function testSetAndGetOptions() {
+ /**
+ * @var StringValueParser $parser
+ */
+ $parser = $this->getInstance();
+
+ $parser->setOptions( new ParserOptions() );
+
+ $this->assertEquals( new ParserOptions(), $parser->getOptions() );
+
+ $options = new ParserOptions();
+ $options->setOption( '~=[,,_,,]:3', '~=[,,_,,]:3' );
+
+ $parser->setOptions( $options );
+
+ $this->assertEquals( $options, $parser->getOptions() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php b/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php
new file mode 100644
index 00000000..f937f810
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/ValueParsers/ValueParserTestBase.php
@@ -0,0 +1,109 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use Comparable;
+use DataValues\DataValue;
+use PHPUnit_Framework_TestCase;
+use ValueParsers\ParserOptions;
+use ValueParsers\ValueParser;
+
+/**
+ * Base for unit tests for ValueParser implementing classes.
+ *
+ * @since 0.1
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class ValueParserTestBase extends PHPUnit_Framework_TestCase {
+
+ /**
+ * @since 0.1
+ *
+ * @return array[]
+ */
+ public abstract function validInputProvider();
+
+ /**
+ * @since 0.1
+ *
+ * @return array[]
+ */
+ public abstract function invalidInputProvider();
+
+ /**
+ * @since 0.1
+ *
+ * @return ValueParser
+ */
+ protected abstract function getInstance();
+
+ /**
+ * @since 0.1
+ *
+ * @dataProvider validInputProvider
+ * @param mixed $value
+ * @param mixed $expected
+ * @param ValueParser|null $parser
+ */
+ public function testParseWithValidInputs( $value, $expected, ValueParser $parser = null ) {
+ if ( $parser === null ) {
+ $parser = $this->getInstance();
+ }
+
+ $this->assertSmartEquals( $expected, $parser->parse( $value ) );
+ }
+
+ /**
+ * @param DataValue|mixed $expected
+ * @param DataValue|mixed $actual
+ */
+ private function assertSmartEquals( $expected, $actual ) {
+ if ( $this->requireDataValue() || $expected instanceof Comparable ) {
+ if ( $expected instanceof DataValue && $actual instanceof DataValue ) {
+ $msg = "testing equals():\n"
+ . preg_replace( '/\s+/', ' ', print_r( $actual->toArray(), true ) ) . " should equal\n"
+ . preg_replace( '/\s+/', ' ', print_r( $expected->toArray(), true ) );
+ } else {
+ $msg = 'testing equals()';
+ }
+
+ $this->assertTrue( $expected->equals( $actual ), $msg );
+ }
+ else {
+ $this->assertEquals( $expected, $actual );
+ }
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @dataProvider invalidInputProvider
+ * @param mixed $value
+ * @param ValueParser|null $parser
+ */
+ public function testParseWithInvalidInputs( $value, ValueParser $parser = null ) {
+ if ( $parser === null ) {
+ $parser = $this->getInstance();
+ }
+
+ $this->setExpectedException( 'ValueParsers\ParseException' );
+ $parser->parse( $value );
+ }
+
+ /**
+ * Returns if the result of the parsing process should be checked to be a DataValue.
+ *
+ * @since 0.1
+ *
+ * @return bool
+ */
+ protected function requireDataValue() {
+ return true;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/common/tests/bootstrap.php b/www/wiki/vendor/data-values/common/tests/bootstrap.php
new file mode 100644
index 00000000..ac82d460
--- /dev/null
+++ b/www/wiki/vendor/data-values/common/tests/bootstrap.php
@@ -0,0 +1,14 @@
+<?php
+
+if ( PHP_SAPI !== 'cli' ) {
+ die( 'Not an entry point' );
+}
+
+error_reporting( E_ALL | E_STRICT );
+ini_set( 'display_errors', 1 );
+
+if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
+ die( 'You need to install this package with Composer before you can run the tests' );
+}
+
+require_once __DIR__ . '/../vendor/autoload.php';
diff --git a/www/wiki/vendor/data-values/data-values/COPYING b/www/wiki/vendor/data-values/data-values/COPYING
new file mode 100644
index 00000000..ebba08a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text contained in
+said file overrides any license information contained in directories of smaller depth.
+Alternative licenses are typically used for software that is provided by external
+parties, and merely packaged with this software for convenience.
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
diff --git a/www/wiki/vendor/data-values/data-values/DataValues.php b/www/wiki/vendor/data-values/data-values/DataValues.php
new file mode 100644
index 00000000..1a8d2db5
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/DataValues.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * Entry point for the DataValues library.
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+
+if ( defined( 'DATAVALUES_VERSION' ) ) {
+ // Do not initialize more than once.
+ return 1;
+}
+
+define( 'DATAVALUES_VERSION', '2.1.1' );
diff --git a/www/wiki/vendor/data-values/data-values/README.md b/www/wiki/vendor/data-values/data-values/README.md
new file mode 100644
index 00000000..a54c7077
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/README.md
@@ -0,0 +1,113 @@
+# DataValues
+
+DataValues is a small PHP library that aims to be a common foundation for representing "simple"
+values. Values such as booleans and strings.
+
+It is part of the [DataValues set of libraries](https://github.com/DataValues).
+
+[![Build Status](https://secure.travis-ci.org/DataValues/DataValues.png?branch=master)](http://travis-ci.org/DataValues/DataValues)
+[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/DataValues/badges/coverage.png?s=56a1ea89df94c6d9b4223ba584d0d4556e1984ef)](https://scrutinizer-ci.com/g/DataValues/DataValues/)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/DataValues/badges/quality-score.png?s=ba9364790e6b521277a3829ffb91e2c2e1b68c3c)](https://scrutinizer-ci.com/g/DataValues/DataValues/)
+
+On [Packagist](https://packagist.org/packages/data-values/data-values):
+[![Latest Stable Version](https://poser.pugx.org/data-values/data-values/version.png)](https://packagist.org/packages/data-values/data-values)
+[![Download count](https://poser.pugx.org/data-values/data-values/d/total.png)](https://packagist.org/packages/data-values/data-values)
+
+## Requirements
+
+These PHP versions are supported:
+
+* PHP 5.5 or later, including PHP 7
+* HHVM 3.3 or later
+
+## Installation
+
+You can use [Composer](http://getcomposer.org/) to download and install
+this package as well as its dependencies. Alternatively you can simply clone
+the git repository and take care of loading yourself.
+
+### Composer
+
+To add this package as a local, per-project dependency to your project, simply add a
+dependency on `data-values/data-values` to your project's `composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a dependency on
+DataValues 2.0:
+
+ {
+ "require": {
+ "data-values/data-values": "^2.0.0"
+ }
+ }
+
+### Manual
+
+Get the DataValues code, either via git, or some other means. Also get all dependencies.
+You can find a list of the dependencies in the "require" section of the composer.json file.
+Load all dependencies and the load the DataValues library by including its entry point:
+DataValues.php.
+
+## Tests
+
+This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these
+tests using the PHPUnit configuration file found in the root directory. The tests can also be run
+via TravisCI, as a TravisCI configuration file is also provided in the root directory.
+
+## Authors
+
+DataValues has been written primarily by [Jeroen De Dauw](https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw),
+in part as [Wikimedia Germany](https://wikimedia.de) employee for the [Wikidata project](https://wikidata.org/).
+
+Contributions where also made by [several other awesome people]
+(https://www.ohloh.net/p/datavalues/contributors).
+
+## Release notes
+
+### 2.1.1 (2017-09-28)
+
+* Fixed `DataValueTest` not being installable via Composer
+
+### 2.1.0 (2017-08-09)
+
+* Removed MediaWiki integration
+
+### 2.0.0 (2017-08-02)
+
+* Dropped `Copyable` interface
+* Dropped deprecated constant `DataValues_VERSION`, use `DATAVALUES_VERSION` instead
+* Deprecated `newFromArray` in all `DataValue` implementations.
+* Fixed and updated documentation throughout the code
+* Removed broken constructor tests
+* Updated minimal required PHP version from 5.3 to 5.5.9
+
+### 1.0.0 (2014-09-26)
+
+* The CI now ensures compatibility with PHP 5.6 and HHVM
+* A lot of type hints where improved
+* Protected methods and fields where changed to private
+* The test bootstrap no longer executes `composer update`
+* The test bootstrap now sets PHP strict mode
+* The contract of the `Hashable::getHash` method was updated
+* The MediaWiki internationalization support has been migrated to the JSON based version
+
+### 0.1.1 (2013-11-22)
+
+* Removed support for running the tests via the MediaWiki test runner.
+* The test bootstrapping file now automatically does a composer install.
+* Removed custom autoloader in favour of defining autoloading in composer.json.
+
+### 0.1.0 (2013-11-16)
+
+Initial release with these features:
+
+* DataValue interface
+ * BooleanValue implementation
+ * NumberValue implementation
+ * StringValue implementation
+ * UnDeserializableValue implementation
+ * UnknownValue implementation
+* Common interface definitions: Comparable, Copyable, Hashable, Immutable
+
+## Links
+
+* [DataValues on Packagist](https://packagist.org/packages/data-values/data-values)
+* [DataValues on Ohloh](https://www.ohloh.net/p/datavalues)
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php
new file mode 100644
index 00000000..0bf01a6f
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/BooleanValue.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a boolean value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class BooleanValue extends DataValueObject {
+
+ private $value;
+
+ /**
+ * @param bool $value
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( $value ) {
+ if ( !is_bool( $value ) ) {
+ throw new IllegalValueException( 'Can only construct BooleanValue from booleans' );
+ }
+
+ $this->value = $value;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string '0' for false, '1' for true.
+ */
+ public function serialize() {
+ return $this->value ? '1' : '0';
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value '0' for false, '1' for true.
+ */
+ public function unserialize( $value ) {
+ $this->value = $value === '1';
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'boolean';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return int 0 for false, 1 for true.
+ */
+ public function getSortKey() {
+ return $this->value ? 1 : 0;
+ }
+
+ /**
+ * Returns the boolean.
+ * @see DataValue::getValue
+ *
+ * @return bool
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * Constructs a new instance from the provided data. Required for @see DataValueDeserializer.
+ * This is expected to round-trip with @see getArrayValue.
+ *
+ * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are
+ * underspecified (not in the DataValue interface), and misleadingly named (should be named
+ * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
+ *
+ * @param mixed $data Warning! Even if this is expected to be a value as returned by
+ * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee
+ * this. This is not guaranteed to be a boolean!
+ *
+ * @throws IllegalValueException if $data is not in the expected format. Subclasses of
+ * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer.
+ * @return self
+ */
+ public static function newFromArray( $data ) {
+ return new static( $data );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php
new file mode 100644
index 00000000..5ead67ba
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValue.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace DataValues;
+
+use Comparable;
+use Hashable;
+use Immutable;
+use Serializable;
+
+/**
+ * Interface for objects that represent a single data value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface DataValue extends Hashable, Comparable, Serializable, Immutable {
+
+ /**
+ * Returns the identifier of the datavalues type.
+ *
+ * This is not to be confused with the DataType provided by the DataTypes extension.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public static function getType();
+
+ /**
+ * Returns a key that can be used to sort the data value with.
+ * It can be either numeric or a string.
+ *
+ * @since 0.1
+ *
+ * @return string|float|int
+ */
+ public function getSortKey();
+
+ /**
+ * Returns the value contained by the DataValue. If this value is not simple and
+ * does not have it's own type that represents it, the DataValue itself will be returned.
+ * In essence, this method returns the "simplest" representation of the value.
+ *
+ * Example:
+ * - NumberValue returns a float or integer
+ * - MediaWikiTitleValue returns a Title object
+ * - QuantityValue returns itself
+ *
+ * @since 0.1
+ *
+ * @return mixed
+ */
+ public function getValue();
+
+ /**
+ * Returns the value in a form suitable for an array serialization.
+ *
+ * For simple values (ie a string) the return value will be equal to that of @see getValue.
+ *
+ * Complex DataValues can provide a nicer implementation though, for instance a
+ * geographical coordinate value could provide an array with keys latitude,
+ * longitude and altitude, each pointing to a simple float value.
+ *
+ * @since 0.1
+ *
+ * @return mixed
+ */
+ public function getArrayValue();
+
+ /**
+ * Returns the whole DataValue in array form.
+ *
+ * The array contains:
+ * - value: mixed, same as the result of @see getArrayValue
+ * - type: string, same as the result of @see getType
+ *
+ * This is sufficient for unserialization in a factory.
+ *
+ * @since 0.1
+ *
+ * @return array
+ */
+ public function toArray();
+
+ /**
+ * Returns a deep copy of the object.
+ *
+ * @since 0.1
+ *
+ * @return DataValue
+ */
+ public function getCopy();
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php
new file mode 100644
index 00000000..a47f330f
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/DataValueObject.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Base for objects that represent a single data value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class DataValueObject implements DataValue {
+
+ /**
+ * @see Hashable::getHash
+ *
+ * @return string
+ */
+ public function getHash() {
+ return md5( serialize( $this ) );
+ }
+
+ /**
+ * @see Comparable::equals
+ *
+ * @param mixed $target
+ *
+ * @return bool
+ */
+ public function equals( $target ) {
+ if ( $this === $target ) {
+ return true;
+ }
+
+ return is_object( $target )
+ && get_called_class() === get_class( $target )
+ && serialize( $this ) === serialize( $target );
+ }
+
+ /**
+ * @see DataValue::getCopy
+ *
+ * @return DataValue
+ */
+ public function getCopy() {
+ return unserialize( serialize( $this ) );
+ }
+
+ /**
+ * @see DataValue::getArrayValue
+ *
+ * @return mixed
+ */
+ public function getArrayValue() {
+ return $this->getValue();
+ }
+
+ /**
+ * @see DataValue::toArray
+ *
+ * @return array
+ */
+ public function toArray() {
+ return [
+ 'value' => $this->getArrayValue(),
+ 'type' => $this->getType(),
+ ];
+ }
+
+ /**
+ * Checks that $data is an array and contains the given fields.
+ *
+ * @param mixed $data
+ * @param string[] $fields
+ *
+ * @todo: this should be removed once we got rid of all the static newFromArray() methods.
+ *
+ * @throws IllegalValueException
+ */
+ protected static function requireArrayFields( $data, array $fields ) {
+ if ( !is_array( $data ) ) {
+ throw new IllegalValueException( "array expected" );
+ }
+
+ foreach ( $fields as $field ) {
+ if ( !array_key_exists( $field, $data ) ) {
+ throw new IllegalValueException( "$field field required" );
+ }
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php b/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php
new file mode 100644
index 00000000..781fb223
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/IllegalValueException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace DataValues;
+
+use InvalidArgumentException;
+
+/**
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ */
+class IllegalValueException extends InvalidArgumentException {
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php
new file mode 100644
index 00000000..7c440758
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/NumberValue.php
@@ -0,0 +1,102 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a simple numeric value.
+ *
+ * More complex numeric values that have associated info such as
+ * unit and accuracy can be represented with a @see QuantityValue.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class NumberValue extends DataValueObject {
+
+ /**
+ * @var int|float
+ */
+ private $value;
+
+ /**
+ * @param int|float $value
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( $value ) {
+ if ( !is_int( $value ) && !is_float( $value ) ) {
+ throw new IllegalValueException( 'Can only construct NumberValue from floats or integers.' );
+ }
+
+ $this->value = $value;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize() {
+ return serialize( $this->value );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ $this->__construct( unserialize( $value ) );
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'number';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return int|float
+ */
+ public function getSortKey() {
+ return $this->value;
+ }
+
+ /**
+ * Returns the number.
+ * @see DataValue::getValue
+ *
+ * @return int|float
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * Constructs a new instance from the provided data. Required for @see DataValueDeserializer.
+ * This is expected to round-trip with @see getArrayValue.
+ *
+ * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are
+ * underspecified (not in the DataValue interface), and misleadingly named (should be named
+ * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
+ *
+ * @param mixed $data Warning! Even if this is expected to be a value as returned by
+ * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee
+ * this. This is not guaranteed to be a number!
+ *
+ * @throws IllegalValueException if $data is not in the expected format. Subclasses of
+ * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer.
+ * @return self
+ */
+ public static function newFromArray( $data ) {
+ return new static( $data );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php
new file mode 100644
index 00000000..7347a6ef
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/StringValue.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a string value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class StringValue extends DataValueObject {
+
+ /**
+ * @var string
+ */
+ private $value;
+
+ /**
+ * @param string $value
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( $value ) {
+ if ( !is_string( $value ) ) {
+ throw new IllegalValueException( 'Can only construct StringValue from strings' );
+ }
+
+ $this->value = $value;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize() {
+ return $this->value;
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ $this->__construct( $value );
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'string';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return string
+ */
+ public function getSortKey() {
+ return $this->value;
+ }
+
+ /**
+ * Returns the string.
+ * @see DataValue::getValue
+ *
+ * @return string
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * Constructs a new instance from the provided data. Required for @see DataValueDeserializer.
+ * This is expected to round-trip with @see getArrayValue.
+ *
+ * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are
+ * underspecified (not in the DataValue interface), and misleadingly named (should be named
+ * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
+ *
+ * @param mixed $data Warning! Even if this is expected to be a value as returned by
+ * @see getArrayValue, callers of this specific newFromArray implementation can not guarantee
+ * this. This is not guaranteed to be a string!
+ *
+ * @throws IllegalValueException if $data is not in the expected format. Subclasses of
+ * InvalidArgumentException are expected and properly handled by @see DataValueDeserializer.
+ * @return self
+ */
+ public static function newFromArray( $data ) {
+ return new static( $data );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php
new file mode 100644
index 00000000..08a1f1c2
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/UnDeserializableValue.php
@@ -0,0 +1,174 @@
+<?php
+
+namespace DataValues;
+
+use InvalidArgumentException;
+
+/**
+ * Class representing a value that could not be unserialized for some reason.
+ * It contains the raw native data structure representing the value,
+ * as well as the originally intended value type and an error message.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ */
+class UnDeserializableValue extends DataValueObject {
+
+ /**
+ * @var mixed
+ */
+ private $data;
+
+ /**
+ * @var string|null
+ */
+ private $type;
+
+ /**
+ * @var string
+ */
+ private $error;
+
+ /**
+ * @param mixed $data The raw data structure
+ * @param string|null $type The originally intended type
+ * @param string $error The error that occurred when processing the original data structure.
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct( $data, $type, $error ) {
+ if ( is_object( $data ) ) {
+ throw new InvalidArgumentException( '$data must not be an object' );
+ }
+
+ if ( !is_string( $type ) && !is_null( $type ) ) {
+ throw new InvalidArgumentException( '$type must be a string or null' );
+ }
+
+ if ( !is_string( $error ) ) {
+ throw new InvalidArgumentException( '$error must be a string' );
+ }
+
+ $this->data = $data;
+ $this->type = $type;
+ $this->error = $error;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @note: The serialization includes the intended type and the error message
+ * along with the original data.
+ *
+ * @return string
+ */
+ public function serialize() {
+ return serialize( [ $this->type, $this->data, $this->error ] );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ list( $type, $data, $error ) = unserialize( $value );
+ $this->__construct( $data, $type, $error );
+ }
+
+ /**
+ * @see DataValue::getArrayValue
+ *
+ * @note: this returns the original raw data structure.
+ *
+ * @return mixed
+ */
+ public function getArrayValue() {
+ return $this->data;
+ }
+
+ /**
+ * @see DataValue::toArray
+ *
+ * @note: This uses the originally intended type. This way, the native representation
+ * does not model a UnDeserializableValue, but the originally intended type of value.
+ * This allows for round trip compatibility with unknown types of data.
+ *
+ * @return array
+ */
+ public function toArray() {
+ return [
+ 'value' => $this->data,
+ 'type' => $this->type,
+ 'error' => $this->error,
+ ];
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'bad';
+ }
+
+ /**
+ * Returns the value type that was intended for the bad data structure.
+ *
+ * @return string|null
+ */
+ public function getTargetType() {
+ return $this->type;
+ }
+
+ /**
+ * Returns a string describing the issue that caused the failure
+ * represented by this UnDeserializableValue object.
+ *
+ * @return string
+ */
+ public function getReason() {
+ return $this->error;
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return int Always 0 in this implementation.
+ */
+ public function getSortKey() {
+ return 0;
+ }
+
+ /**
+ * Returns the raw data structure.
+ * @see DataValue::getValue
+ *
+ * @return mixed
+ */
+ public function getValue() {
+ return $this->data;
+ }
+
+ /**
+ * @see Comparable::equals
+ *
+ * @param mixed $target
+ *
+ * @return bool
+ */
+ public function equals( $target ) {
+ if ( $this === $target ) {
+ return true;
+ }
+
+ return $target instanceof self
+ && $this->data === $target->data
+ && $this->type === $target->type
+ && $this->error === $target->error;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php b/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php
new file mode 100644
index 00000000..4c0c84ad
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/DataValues/UnknownValue.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace DataValues;
+
+/**
+ * Class representing a value of unknown type.
+ * This is in essence a null-wrapper, useful for instance for null-parsers.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class UnknownValue extends DataValueObject {
+
+ /**
+ * @var mixed
+ */
+ private $value;
+
+ /**
+ * @param mixed $value
+ */
+ public function __construct( $value ) {
+ $this->value = $value;
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize() {
+ return serialize( $this->value );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ */
+ public function unserialize( $value ) {
+ $this->__construct( unserialize( $value ) );
+ }
+
+ /**
+ * @see DataValue::getType
+ *
+ * @return string
+ */
+ public static function getType() {
+ return 'unknown';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ *
+ * @return int Always 0 in this implementation.
+ */
+ public function getSortKey() {
+ return 0;
+ }
+
+ /**
+ * Returns the value.
+ * @see DataValue::getValue
+ *
+ * @return mixed
+ */
+ public function getValue() {
+ return $this->value;
+ }
+
+ /**
+ * @see Comparable::equals
+ *
+ * @param mixed $target
+ *
+ * @return bool
+ */
+ public function equals( $target ) {
+ if ( $this === $target ) {
+ return true;
+ }
+
+ return $target instanceof self
+ && $this->value === $target->value;
+ }
+
+ /**
+ * Constructs a new instance from the provided data. Required for @see DataValueDeserializer.
+ * This is expected to round-trip with @see getArrayValue.
+ *
+ * @deprecated since 1.1. Static DataValue::newFromArray constructors like this are
+ * underspecified (not in the DataValue interface), and misleadingly named (should be named
+ * newFromArrayValue). Instead, use DataValue builder callbacks in @see DataValueDeserializer.
+ *
+ * @param mixed $data
+ *
+ * @return self
+ */
+ public static function newFromArray( $data ) {
+ return new static( $data );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php
new file mode 100644
index 00000000..159180ad
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Comparable.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * Interface for objects that have an equals method.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface Comparable {
+
+ /**
+ * Returns if the provided value is equal to the object or not.
+ *
+ * @since 0.1
+ *
+ * @param mixed $target
+ *
+ * @return bool
+ */
+ public function equals( $target );
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php
new file mode 100644
index 00000000..dba1c531
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Hashable.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * Interface for objects that have a getHash method.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface Hashable {
+
+ /**
+ * Returns a string hash based on the value of the object. The string must not exceed
+ * 255 bytes (255 ASCII characters or less when it contains Unicode characters that
+ * need to be UTF-8 encoded) to allow using indexes on all database systems.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getHash();
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php b/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php
new file mode 100644
index 00000000..c426c523
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/src/interfaces/Immutable.php
@@ -0,0 +1,14 @@
+<?php
+
+/**
+ * Interface for immutable objects.
+ * The interface does not specify any methods and merely acts as a flag.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface Immutable {
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/bootstrap.php b/www/wiki/vendor/data-values/data-values/tests/bootstrap.php
new file mode 100644
index 00000000..43a36171
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/bootstrap.php
@@ -0,0 +1,14 @@
+<?php
+
+if ( PHP_SAPI !== 'cli' ) {
+ die( 'Not an entry point' );
+}
+
+error_reporting( -1 );
+ini_set( 'display_errors', 1 );
+
+if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
+ die( 'You need to install this package with Composer before you can run the tests' );
+}
+
+require_once __DIR__ . '/../vendor/autoload.php';
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php
new file mode 100644
index 00000000..4a04a917
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/BooleanValueTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\BooleanValue;
+
+/**
+ * @covers DataValues\BooleanValue
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class BooleanValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return BooleanValue::class;
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ false ];
+ $argLists[] = [ true ];
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 42 ];
+ $argLists[] = [ [] ];
+ $argLists[] = [ '1' ];
+ $argLists[] = [ '' ];
+ $argLists[] = [ 0 ];
+ $argLists[] = [ 1 ];
+ $argLists[] = [ 'foo' ];
+ $argLists[] = [ null ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValue( BooleanValue $boolean, array $arguments ) {
+ $this->assertEquals( $arguments[0], $boolean->getValue() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php
new file mode 100644
index 00000000..f420bc61
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/DataValueTest.php
@@ -0,0 +1,199 @@
+<?php
+
+namespace DataValues\Tests;
+
+use Comparable;
+use DataValues\DataValue;
+use Exception;
+use Hashable;
+use Immutable;
+use PHPUnit_Framework_TestCase;
+use ReflectionClass;
+use Serializable;
+
+/**
+ * Base for unit tests for DataValue implementing classes.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class DataValueTest extends PHPUnit_Framework_TestCase {
+
+ /**
+ * Returns the name of the concrete class tested by this test.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ abstract public function getClass();
+
+ abstract public function validConstructorArgumentsProvider();
+
+ abstract public function invalidConstructorArgumentsProvider();
+
+ /**
+ * Creates and returns a new instance of the concrete class.
+ *
+ * @since 0.1
+ *
+ * @return mixed
+ */
+ public function newInstance() {
+ $reflector = new ReflectionClass( $this->getClass() );
+ $args = func_get_args();
+ $instance = $reflector->newInstanceArgs( $args );
+ return $instance;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @return array [instance, constructor args]
+ */
+ public function instanceProvider() {
+ $instanceBuilder = [ $this, 'newInstance' ];
+
+ return array_map(
+ function ( array $args ) use ( $instanceBuilder ) {
+ return [
+ call_user_func_array( $instanceBuilder, $args ),
+ $args
+ ];
+ },
+ $this->validConstructorArgumentsProvider()
+ );
+ }
+
+ /**
+ * @dataProvider validConstructorArgumentsProvider
+ *
+ * @since 0.1
+ */
+ public function testConstructorWithValidArguments() {
+ $dataItem = call_user_func_array(
+ [ $this, 'newInstance' ],
+ func_get_args()
+ );
+
+ $this->assertInstanceOf( $this->getClass(), $dataItem );
+ }
+
+ /**
+ * @dataProvider invalidConstructorArgumentsProvider
+ *
+ * @since 0.1
+ */
+ public function testConstructorWithInvalidArguments() {
+ $this->setExpectedException( Exception::class );
+
+ call_user_func_array(
+ [ $this, 'newInstance' ],
+ func_get_args()
+ );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testImplements( DataValue $value, array $arguments ) {
+ $this->assertInstanceOf( Immutable::class, $value );
+ $this->assertInstanceOf( Hashable::class, $value );
+ $this->assertInstanceOf( Comparable::class, $value );
+ $this->assertInstanceOf( Serializable::class, $value );
+ $this->assertInstanceOf( DataValue::class, $value );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetType( DataValue $value, array $arguments ) {
+ $valueType = $value->getType();
+ $this->assertInternalType( 'string', $valueType );
+ $this->assertTrue( strlen( $valueType ) > 0 );
+
+ // Check whether using getType statically returns the same as called from an instance:
+ $staticValueType = call_user_func( [ $this->getClass(), 'getType' ] );
+ $this->assertEquals( $staticValueType, $valueType );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testSerialization( DataValue $value, array $arguments ) {
+ $serialization = serialize( $value );
+ $this->assertInternalType( 'string', $serialization );
+
+ $unserialized = unserialize( $serialization );
+ $this->assertInstanceOf( DataValue::class, $unserialized );
+
+ $this->assertTrue( $value->equals( $unserialized ) );
+ $this->assertEquals( $value, $unserialized );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testEquals( DataValue $value, array $arguments ) {
+ $this->assertTrue( $value->equals( $value ) );
+
+ foreach ( [ true, false, null, 'foo', 42, [], 4.2 ] as $otherValue ) {
+ $this->assertFalse( $value->equals( $otherValue ) );
+ }
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetHash( DataValue $value, array $arguments ) {
+ $hash = $value->getHash();
+
+ $this->assertInternalType( 'string', $hash );
+ $this->assertEquals( $hash, $value->getHash() );
+ $this->assertEquals( $hash, $value->getCopy()->getHash() );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetCopy( DataValue $value, array $arguments ) {
+ $copy = $value->getCopy();
+
+ $this->assertInstanceOf( DataValue::class, $copy );
+ $this->assertTrue( $value->equals( $copy ) );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValueSimple( DataValue $value, array $arguments ) {
+ $value->getValue();
+ $this->assertTrue( true );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetArrayValueSimple( DataValue $value, array $arguments ) {
+ $value->getArrayValue();
+ $this->assertTrue( true );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testToArray( DataValue $value, array $arguments ) {
+ $array = $value->toArray();
+
+ $this->assertInternalType( 'array', $array );
+
+ $this->assertTrue( array_key_exists( 'type', $array ) );
+ $this->assertTrue( array_key_exists( 'value', $array ) );
+
+ $this->assertEquals( $value->getType(), $array['type'] );
+ $this->assertEquals( $value->getArrayValue(), $array['value'] );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php
new file mode 100644
index 00000000..7f1b5b12
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/NumberValueTest.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\NumberValue;
+
+/**
+ * @covers DataValues\NumberValue
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class NumberValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return NumberValue::class;
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 42 ];
+ $argLists[] = [ -42 ];
+ $argLists[] = [ 4.2 ];
+ $argLists[] = [ -4.2 ];
+ $argLists[] = [ 0 ];
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 'foo' ];
+ $argLists[] = [ '' ];
+ $argLists[] = [ '0' ];
+ $argLists[] = [ '42' ];
+ $argLists[] = [ '-42' ];
+ $argLists[] = [ '4.2' ];
+ $argLists[] = [ '-4.2' ];
+ $argLists[] = [ false ];
+ $argLists[] = [ true ];
+ $argLists[] = [ null ];
+ $argLists[] = [ '0x20' ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValue( NumberValue $number, array $arguments ) {
+ $this->assertEquals( $arguments[0], $number->getValue() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php
new file mode 100644
index 00000000..dbce05b2
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/StringValueTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\StringValue;
+
+/**
+ * @covers DataValues\StringValue
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class StringValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return StringValue::class;
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 'foo' ];
+ $argLists[] = [ '' ];
+ $argLists[] = [ ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ];
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 42 ];
+ $argLists[] = [ [] ];
+ $argLists[] = [ false ];
+ $argLists[] = [ true ];
+ $argLists[] = [ null ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValue( StringValue $string, array $arguments ) {
+ $this->assertEquals( $arguments[0], $string->getValue() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php
new file mode 100644
index 00000000..4d132fcb
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnDeserializableValueTest.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\DataValue;
+use DataValues\UnDeserializableValue;
+
+/**
+ * @covers DataValues\UnDeserializableValue
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ */
+class UnDeserializableValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return UnDeserializableValue::class;
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ null, null, 'No type and no data' ];
+ $argLists[] = [ null, 'string', 'A type but no data' ];
+ $argLists[] = [ [ 'stuff' ], 'string', 'A type and bad data' ];
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ new \stdClass(), null, 'No type and no data' ];
+ $argLists[] = [ null, 42, 'No type and no data' ];
+ $argLists[] = [ null, false, 'No type and no data' ];
+ $argLists[] = [ null, [], 'No type and no data' ];
+ $argLists[] = [ null, null, null ];
+ $argLists[] = [ null, null, true ];
+ $argLists[] = [ null, null, [] ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValue( UnDeserializableValue $value, array $arguments ) {
+ $this->assertEquals( $arguments[0], $value->getValue() );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetArrayValue( UnDeserializableValue $value, array $arguments ) {
+ $this->assertEquals( $arguments[0], $value->getArrayValue() );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetTargetType( UnDeserializableValue $value, array $arguments ) {
+ $this->assertEquals( $arguments[1], $value->getTargetType() );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testToArray( DataValue $value, array $arguments ) {
+ $array = $value->toArray();
+
+ $this->assertInternalType( 'array', $array );
+
+ $this->assertTrue( array_key_exists( 'type', $array ) );
+ $this->assertTrue( array_key_exists( 'value', $array ) );
+
+ $this->assertEquals( $value->getTargetType(), $array['type'] );
+ $this->assertEquals( $value->getValue(), $array['value'] );
+ }
+
+ public function testNewFromArray() {
+ $this->assertFalse( method_exists( $this->getClass(), 'newFromArray' ) );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php
new file mode 100644
index 00000000..d3d79029
--- /dev/null
+++ b/www/wiki/vendor/data-values/data-values/tests/phpunit/UnknownValueTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace DataValues\Tests;
+
+use DataValues\UnknownValue;
+
+/**
+ * @covers DataValues\UnknownValue
+ *
+ * @group DataValue
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class UnknownValueTest extends DataValueTest {
+
+ /**
+ * @see DataValueTest::getClass
+ *
+ * @return string
+ */
+ public function getClass() {
+ return UnknownValue::class;
+ }
+
+ public function validConstructorArgumentsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 42 ];
+ $argLists[] = [ [] ];
+ $argLists[] = [ false ];
+ $argLists[] = [ true ];
+ $argLists[] = [ null ];
+ $argLists[] = [ 'foo' ];
+ $argLists[] = [ '' ];
+ $argLists[] = [ ' foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz foo bar baz ' ];
+
+ return $argLists;
+ }
+
+ public function invalidConstructorArgumentsProvider() {
+ return [
+ [],
+ ];
+ }
+
+ public function testConstructorWithInvalidArguments() {
+ // UnknownValue has no invalid arguments
+ $this->assertTrue( true );
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testGetValue( UnknownValue $value, array $arguments ) {
+ $this->assertEquals( $arguments[0], $value->getValue() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/COPYING b/www/wiki/vendor/data-values/geo/COPYING
new file mode 100644
index 00000000..ebba08a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text contained in
+said file overrides any license information contained in directories of smaller depth.
+Alternative licenses are typically used for software that is provided by external
+parties, and merely packaged with this software for convenience.
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
diff --git a/www/wiki/vendor/data-values/geo/README.md b/www/wiki/vendor/data-values/geo/README.md
new file mode 100644
index 00000000..9a868c00
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/README.md
@@ -0,0 +1,280 @@
+# DataValues Geo
+
+Small library for **parsing, formatting and representing coordinates**. This library supports multiple coordinate formats,
+it is well tested, and it is used by the software behind Wikipedia and Wikidata.
+
+[![Build Status](https://travis-ci.org/DataValues/Geo.svg?branch=master)](https://travis-ci.org/DataValues/Geo)
+[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Geo/badges/coverage.png?s=bf4cfd11f3b985fd05918f395c350b376a9ce0ee)](https://scrutinizer-ci.com/g/DataValues/Geo/)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Geo/badges/quality-score.png?s=e695e42b53d74fc02e5cfa2aa218420f062edbd2)](https://scrutinizer-ci.com/g/DataValues/Geo/)
+
+On [Packagist](https://packagist.org/packages/data-values/geo):
+[![Latest Stable Version](https://poser.pugx.org/data-values/geo/version.png)](https://packagist.org/packages/data-values/geo)
+[![Download count](https://poser.pugx.org/data-values/geo/d/total.png)](https://packagist.org/packages/data-values/geo)
+
+## Usage
+
+To **parse a string to a `LatLongValue` object** you use one of the coordinate parsers.
+
+```php
+$parser = new LatLongParser();
+$latLongValue = $parser->parse('55.7557860 N, 37.6176330 W');
+var_dump($latLongValue->getLongitude()); // float: -37.6176330
+```
+
+These parsers are provided:
+
+* `LatLongParser` - Facade for format specific parsers. In most cases you will be using this one
+* `DdCoordinateParser` - Parses decimal degree coordinates
+* `DmCoordinateParser` - Parses decimal minute coordinates
+* `DmsCoordinateParser` - Parses degree minute second coordinates
+* `FloatCoordinateParser` - Parses float coordinates
+* `GlobeCoordinateParser` - Parses coordinates into `GlobeCoordinateValue` objects
+
+To **turn a coordinate object into a string** you use one of the coordinate formatters.
+
+```php
+$formatter = new LatLongFormatter();
+$coordinateString = $formatter->format(new LatLongValue(42.23, 13.37));
+```
+
+These formatters are provided:
+
+* `LatLongFormatter` - Formats a `LatLongValue` into any of the supported formats
+* `GlobeCoordinateFormatter` - Formats a `GlobeCoordinateValue`
+
+To **represent a set of coordinates** you use one of the Value Objects.
+
+`LatLongValue` has a float latitude and longitude. `GlobeCoordinateValue` wraps `LatLongValue`
+and adds a precision and a globe identifier.
+
+The **supported coordinate formats** are:
+
+* Degree minute second (`55° 45' 20.8296", -37° 37' 3.4788"` or `55° 45' 20.8296" N, 37° 37' 3.4788" W`)
+* Decimal minute (`55° 30', -37° 30'` or `55° 30' N, 37° 30' W`)
+* Decimal degree (`55.7557860°, -37.6176330°` or `55.7557860° N, 37.6176330° W`)
+* Float (`55.7557860, -37.6176330` or `55.7557860 N, 37.6176330 W`)
+
+The parsers and formatters allow you to customize the used symbols for degrees, minutes and seconds and
+to change the letters used to indicate direction (N, E, S, W).
+
+## Requirements
+
+**Geo 4.x:** PHP 7.1 or later (tested with PHP 7.1 up to PHP 7.3)
+
+**Geo 3.x:** PHP 5.5 or later (tested with PHP 5.5 up to PHP 7.2 and HHVM)
+
+## Installation
+
+To add this package as a local, per-project dependency to your project, simply add a
+dependency on `data-values/geo` to your project's `composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a dependency on
+version 4.x of this package:
+
+```json
+ {
+ "require": {
+ "data-values/geo": "^4.0.0"
+ }
+ }
+```
+
+## Running the tests
+
+For tests only
+
+ composer test
+
+For style checks only
+
+ composer cs
+
+For a full CI run
+
+ composer ci
+
+## Authors
+
+DataValues Geo is based upon and contains a lot of code written by
+[Jeroen De Dauw](https://github.com/JeroenDeDauw) for the
+[Maps](https://github.com/JeroenDeDauw/Maps) and
+[Semantic MediaWiki](https://semantic-mediawiki.org/) projects.
+
+Significant contributions where made by the Wikidata team, as [Wikimedia Germany](https://wikimedia.de/en)
+employees for the [Wikidata project](https://wikidata.org/).
+
+## Release notes
+
+### 4.1.0 (dev)
+
+* Added "PHP strict types" to all files
+* `LatLongValue` no longer extends `DataValueObject`
+* `GlobeCoordinateValue` no longer extends `DataValueObject`
+
+### 4.0.1 (2018-08-10)
+
+* Fixed parsing of coordinates with lowercase S/W directions
+* Fixed parsing DMS coordinates that omit a single minute number
+
+### 3.0.1 (2018-08-01)
+
+* Fixed parsing of coordinates with lowercase S/W directions
+
+### 2.1.2 (2018-08-01)
+
+* Fixed parsing of coordinates with lowercase S/W directions
+
+### 4.0.0 (2018-07-13)
+
+* Updated minimum required PHP version from 5.5.9 to 7.1
+* Added scalar type hints
+* Added return type hints
+* Added nullable type hints
+* Made constant visibility explicit
+* Constructing an invalid `LatLongValue` now causes `InvalidArgumentException` instead of `OutOfRangeException`
+
+### 3.0.0 (2018-03-20)
+
+* Removed `DATAVALUES_GEO_VERSION` constant
+* The parsers no longer extend `StringValueParser`
+ * They no longer have public methods `setOptions` and `getOptions`
+ * They no longer have protected field `options`
+ * They no longer have protected methods `requireOption`, `defaultOption` and `stringParse`
+ * `GlobeCoordinateParser` and `LatLongParser` no longer have protected method `getOption`
+* Made several protected fields and methods private
+ * All fields of `LatLongValue`
+ * The `detect…Precision` methods in `GlobeCoordinateParser`
+ * `LatLongParser::getParsers`
+* Removed public static method `LatLongParser::areCoordinates`
+* Dropped dependence on the DataValues Common library
+* Removed long deprecated class aliases
+ * `DataValues\GlobeCoordinateValue` (now in `DataValues\Geo\Values`)
+ * `DataValues\LatLongValue` (now in `DataValues\Geo\Values`)
+ * `DataValues\Geo\Formatters\GeoCoordinateFormatter` (now `LatLongFormatter`)
+ * `DataValues\Geo\Parsers\GeoCoordinateParser` (now `LatLongParser`)
+
+### 2.1.1 (2017-08-09)
+
+* Allow use with ~0.4.0 of DataValues/Common
+
+### 2.1.0 (2017-08-09)
+
+* Remove MediaWiki integration
+* Make use of the …::class feature
+* Add .gitattributes to exclude not needed files from git exports
+* Use Wikibase CodeSniffer instead of Mediawiki's
+* Move to short array syntax
+
+### 2.0.1 (2017-06-26)
+
+* Fixed `GlobeCoordinateValue::newFromArray` and `LatLongValue::newFromArray` not accepting mixed
+ values.
+* Deprecated `GlobeCoordinateValue::newFromArray` and `LatLongValue::newFromArray`.
+* Updated minimum required PHP version from 5.3 to 5.5.9.
+
+### 2.0.0 (2017-05-09)
+
+* `GlobeCoordinateValue` does not accept empty strings as globes any more.
+* `GlobeCoordinateValue` does not accept precisions outside the [-360..+360] interval any more.
+* Changed hash calculation of `GlobeCoordinateValue` in an incompatible way.
+* Renamed `GeoCoordinateFormatter` to `LatLongFormatter`, leaving a deprecated alias.
+* Renamed `GeoCoordinateParser` to `LatLongParser`, leaving a deprecated alias.
+* Renamed `GeoCoordinateParserBase` to `LatLongParserBase`.
+* Deprecated `LatLongParser::areCoordinates`.
+
+### 1.2.2 (2017-03-14)
+
+* Fixed multiple rounding issues in `GeoCoordinateFormatter`.
+
+### 1.2.1 (2016-12-16)
+
+* Fixed another IEEE issue in `GeoCoordinateFormatter`.
+
+### 1.2.0 (2016-11-11)
+
+* Added missing inline documentation to public methods and constants.
+* Added a basic PHPCS rule set, can be run with `composer phpcs`.
+
+### 1.1.8 (2016-10-12)
+
+* Fixed an IEEE issue in `GeoCoordinateFormatter`
+* Fixed a PHP 7.1 compatibility issue in a test
+
+### 1.1.7 (2016-05-25)
+
+* Made minor documentation improvements
+
+### 1.1.6 (2016-04-02)
+
+* Added compatibility with DataValues Common 0.3.x
+
+### 1.1.5 (2015-12-28)
+
+* The component can now be installed together with DataValues Interfaces 0.2.x
+
+### 1.1.4 (2014-11-25)
+
+* Add fall back to default on invalid precision to more places.
+
+### 1.1.3 (2014-11-19)
+
+* Fall back to default on invalid precision instead of dividing by zero.
+
+### 1.1.2 (2014-11-18)
+
+* Precision detection in `GlobeCoordinateParser` now has a lower bound of 0.00000001°
+
+### 1.1.1 (2014-10-21)
+
+* Removed remaining uses of class aliases from messages and comments
+* Fixed some types in documentation
+
+### 1.1.0 (2014-10-09)
+
+* Made the component installable with DataValues 1.x
+* `GeoCoordinateFormatter` now supports precision in degrees
+* `GlobeCoordinateFormatter` now passes the globe precision to the `GeoCoordinateFormatter` it uses
+* Introduced `FORMAT_NAME` class constants on ValueParsers in order to use them as expectedFormat
+* Changed ValueParsers to pass rawValue and expectedFormat arguments when constructing a `ParseException`
+
+### 1.0.0 (2014-07-31)
+
+* All classes and interfaces have been moved into the `DataValues\Geo` namespace
+ * `DataValues\LatLongValue` has been left as deprecated alias
+ * `DataValues\GlobeCoordinateValue` has been left as deprecated alias
+* Globe in `GlobeCoordinateValue` now defaults to `http://www.wikidata.org/entity/Q2`
+
+### 0.2.0 (2014-07-07)
+
+* Removed deprecated `GeoCoordinateValue`
+* Added `GlobeMath`
+
+### 0.1.2 (2014-01-22)
+
+* Added support for different levels of spacing in GeoCoordinateFormatter
+
+### 0.1.1 (2013-11-30)
+
+* Added support for direction notation to GeoCoordinateFormatter
+* Decreased complexity of GeoCoordinateFormatter
+* Decreased complexity and coupling of GeoCoordinateFormatterTest
+
+### 0.1.0 (2013-11-17)
+
+Initial release with these features:
+
+* LatLongValue
+* GlobeCoordinateValue
+* GeoCoordinateFormatter
+* GlobeCoordinateFormatter
+* DdCoordinateParser
+* DmCoordinateParser
+* DmsCoordinateParser
+* FloatCoordinateParser
+* GeoCoordinateParser
+* GlobeCoordinateParser
+
+## Links
+
+* [DataValues Geo on Packagist](https://packagist.org/packages/data-values/geo)
+* [DataValues Geo on TravisCI](https://travis-ci.org/DataValues/Geo)
+* [DataValues on Wikimedia's Phabricator](https://phabricator.wikimedia.org/project/view/122/)
diff --git a/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php b/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php
new file mode 100644
index 00000000..b651e8a5
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Formatters/GlobeCoordinateFormatter.php
@@ -0,0 +1,53 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Formatters;
+
+use DataValues\Geo\Values\GlobeCoordinateValue;
+use InvalidArgumentException;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\ValueFormatter;
+
+/**
+ * Geographical coordinates formatter.
+ * Formats GlobeCoordinateValue objects.
+ *
+ * Formatting of latitude and longitude is done via LatLongFormatter.
+ *
+ * For now this is a trivial implementation that only forwards to LatLongFormatter.
+ * TODO: add formatting of globe and precision
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class GlobeCoordinateFormatter implements ValueFormatter {
+
+ /**
+ * @var LatLongFormatter
+ */
+ private $formatter;
+
+ public function __construct( FormatterOptions $options = null ) {
+ $this->formatter = new LatLongFormatter( $options );
+ }
+
+ /**
+ * @see ValueFormatter::format
+ *
+ * @param GlobeCoordinateValue $value
+ *
+ * @return string Plain text
+ * @throws InvalidArgumentException
+ */
+ public function format( $value ): string {
+ if ( !( $value instanceof GlobeCoordinateValue ) ) {
+ throw new InvalidArgumentException( 'Data value type mismatch. Expected a GlobeCoordinateValue.' );
+ }
+
+ return $this->formatter->formatLatLongValue( $value->getLatLong(), $value->getPrecision() );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php b/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php
new file mode 100644
index 00000000..94e7828e
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Formatters/LatLongFormatter.php
@@ -0,0 +1,360 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Formatters;
+
+use DataValues\Geo\Values\LatLongValue;
+use InvalidArgumentException;
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\ValueFormatterBase;
+
+/**
+ * Geographical coordinates formatter.
+ * Formats LatLongValue objects.
+ *
+ * Supports the following notations:
+ * - Degree minute second
+ * - Decimal degrees
+ * - Decimal minutes
+ * - Float
+ *
+ * Some code in this class has been borrowed from the
+ * MapsCoordinateParser class of the Maps extension for MediaWiki.
+ *
+ * @since 0.1, renamed in 2.0
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Addshore
+ * @author Thiemo Kreuz
+ */
+class LatLongFormatter extends ValueFormatterBase {
+
+ /**
+ * Output formats for use with the self::OPT_FORMAT option.
+ */
+ public const TYPE_FLOAT = 'float';
+ public const TYPE_DMS = 'dms';
+ public const TYPE_DM = 'dm';
+ public const TYPE_DD = 'dd';
+
+ /**
+ * The symbols representing the different directions for usage in directional notation.
+ * @since 0.1
+ */
+ public const OPT_NORTH_SYMBOL = 'north';
+ public const OPT_EAST_SYMBOL = 'east';
+ public const OPT_SOUTH_SYMBOL = 'south';
+ public const OPT_WEST_SYMBOL = 'west';
+
+ /**
+ * The symbols representing degrees, minutes and seconds.
+ * @since 0.1
+ */
+ public const OPT_DEGREE_SYMBOL = 'degree';
+ public const OPT_MINUTE_SYMBOL = 'minute';
+ public const OPT_SECOND_SYMBOL = 'second';
+
+ /**
+ * Flags for use with the self::OPT_SPACING_LEVEL option.
+ */
+ public const OPT_SPACE_LATLONG = 'latlong';
+ public const OPT_SPACE_DIRECTION = 'direction';
+ public const OPT_SPACE_COORDPARTS = 'coordparts';
+
+ /**
+ * Option specifying the output format (also referred to as output type). Must be one of the
+ * self::TYPE_… constants.
+ */
+ public const OPT_FORMAT = 'geoformat';
+
+ /**
+ * Boolean option specifying if negative coordinates should have minus signs, e.g. "-1°, -2°"
+ * (false) or cardinal directions, e.g. "1° S, 2° W" (true). Default is false.
+ */
+ public const OPT_DIRECTIONAL = 'directional';
+
+ /**
+ * Option for the separator character between latitude and longitude. Defaults to a comma.
+ */
+ public const OPT_SEPARATOR_SYMBOL = 'separator';
+
+ /**
+ * Option specifying the amount and position of space characters in the output. Must be an array
+ * containing zero or more of the self::OPT_SPACE_… flags.
+ */
+ public const OPT_SPACING_LEVEL = 'spacing';
+
+ /**
+ * Option specifying the precision in fractional degrees. Must be a number or numeric string.
+ */
+ public const OPT_PRECISION = 'precision';
+
+ private const DEFAULT_PRECISION = 1 / 3600;
+
+ public function __construct( FormatterOptions $options = null ) {
+ parent::__construct( $options );
+
+ $this->defaultOption( self::OPT_NORTH_SYMBOL, 'N' );
+ $this->defaultOption( self::OPT_EAST_SYMBOL, 'E' );
+ $this->defaultOption( self::OPT_SOUTH_SYMBOL, 'S' );
+ $this->defaultOption( self::OPT_WEST_SYMBOL, 'W' );
+
+ $this->defaultOption( self::OPT_DEGREE_SYMBOL, '°' );
+ $this->defaultOption( self::OPT_MINUTE_SYMBOL, "'" );
+ $this->defaultOption( self::OPT_SECOND_SYMBOL, '"' );
+
+ $this->defaultOption( self::OPT_FORMAT, self::TYPE_FLOAT );
+ $this->defaultOption( self::OPT_DIRECTIONAL, false );
+
+ $this->defaultOption( self::OPT_SEPARATOR_SYMBOL, ',' );
+ $this->defaultOption( self::OPT_SPACING_LEVEL, [
+ self::OPT_SPACE_LATLONG,
+ self::OPT_SPACE_DIRECTION,
+ self::OPT_SPACE_COORDPARTS,
+ ] );
+ $this->defaultOption( self::OPT_PRECISION, 0 );
+ }
+
+ /**
+ * @see ValueFormatter::format
+ *
+ * Calls formatLatLongValue() using OPT_PRECISION for the $precision parameter.
+ *
+ * @param LatLongValue $value
+ *
+ * @return string Plain text
+ * @throws InvalidArgumentException
+ */
+ public function format( $value ): string {
+ if ( !( $value instanceof LatLongValue ) ) {
+ throw new InvalidArgumentException( 'Data value type mismatch. Expected a LatLongValue.' );
+ }
+
+ return $this->formatLatLongValue( $value, $this->getPrecisionFromOptions() );
+ }
+
+ private function getPrecisionFromOptions(): float {
+ $precision = $this->options->getOption( self::OPT_PRECISION );
+
+ if ( is_string( $precision ) ) {
+ return (float)$precision;
+ }
+
+ if ( is_float( $precision ) || is_int( $precision ) ) {
+ return $precision;
+ }
+
+ return self::DEFAULT_PRECISION;
+ }
+
+ /**
+ * Formats a LatLongValue with the desired precision.
+ *
+ * @since 0.5
+ *
+ * @param LatLongValue $value
+ * @param float|int $precision The desired precision, given as fractional degrees.
+ *
+ * @return string Plain text
+ * @throws InvalidArgumentException
+ */
+ public function formatLatLongValue( LatLongValue $value, ?float $precision ): string {
+ if ( $precision <= 0 || !is_finite( $precision ) ) {
+ $precision = self::DEFAULT_PRECISION;
+ }
+
+ $formatted = implode(
+ $this->getOption( self::OPT_SEPARATOR_SYMBOL ) . $this->getSpacing( self::OPT_SPACE_LATLONG ),
+ [
+ $this->formatLatitude( $value->getLatitude(), $precision ),
+ $this->formatLongitude( $value->getLongitude(), $precision )
+ ]
+ );
+
+ return $formatted;
+ }
+
+ /**
+ * @param string $spacingLevel One of the self::OPT_SPACE_… constants
+ *
+ * @return string
+ */
+ private function getSpacing( string $spacingLevel ): string {
+ if ( in_array( $spacingLevel, $this->getOption( self::OPT_SPACING_LEVEL ) ) ) {
+ return ' ';
+ }
+ return '';
+ }
+
+ private function formatLatitude( float $latitude, float $precision ): string {
+ return $this->makeDirectionalIfNeeded(
+ $this->formatCoordinate( $latitude, $precision ),
+ $this->options->getOption( self::OPT_NORTH_SYMBOL ),
+ $this->options->getOption( self::OPT_SOUTH_SYMBOL )
+ );
+ }
+
+ private function formatLongitude( float $longitude, float $precision ): string {
+ return $this->makeDirectionalIfNeeded(
+ $this->formatCoordinate( $longitude, $precision ),
+ $this->options->getOption( self::OPT_EAST_SYMBOL ),
+ $this->options->getOption( self::OPT_WEST_SYMBOL )
+ );
+ }
+
+ private function makeDirectionalIfNeeded( string $coordinate, string $positiveSymbol,
+ string $negativeSymbol ): string {
+
+ if ( $this->options->getOption( self::OPT_DIRECTIONAL ) ) {
+ return $this->makeDirectional( $coordinate, $positiveSymbol, $negativeSymbol );
+ }
+
+ return $coordinate;
+ }
+
+ private function makeDirectional( string $coordinate, string $positiveSymbol,
+ string $negativeSymbol ): string {
+
+ $isNegative = substr( $coordinate, 0, 1 ) === '-';
+
+ if ( $isNegative ) {
+ $coordinate = substr( $coordinate, 1 );
+ }
+
+ $symbol = $isNegative ? $negativeSymbol : $positiveSymbol;
+
+ return $coordinate . $this->getSpacing( self::OPT_SPACE_DIRECTION ) . $symbol;
+ }
+
+ private function formatCoordinate( float $degrees, float $precision ): string {
+ // Remove insignificant detail
+ $degrees = $this->roundDegrees( $degrees, $precision );
+ $format = $this->getOption( self::OPT_FORMAT );
+
+ if ( $format === self::TYPE_FLOAT ) {
+ return $this->getInFloatFormat( $degrees );
+ }
+
+ if ( $format !== self::TYPE_DD ) {
+ if ( $precision >= 1 - 1 / 60 && $precision < 1 ) {
+ $precision = 1;
+ } elseif ( $precision >= 1 / 60 - 1 / 3600 && $precision < 1 / 60 ) {
+ $precision = 1 / 60;
+ }
+ }
+
+ if ( $format === self::TYPE_DD || $precision >= 1 ) {
+ return $this->getInDecimalDegreeFormat( $degrees, $precision );
+ }
+ if ( $format === self::TYPE_DM || $precision >= 1 / 60 ) {
+ return $this->getInDecimalMinuteFormat( $degrees, $precision );
+ }
+ if ( $format === self::TYPE_DMS ) {
+ return $this->getInDegreeMinuteSecondFormat( $degrees, $precision );
+ }
+
+ throw new InvalidArgumentException( 'Invalid coordinate format specified in the options' );
+ }
+
+ private function roundDegrees( float $degrees, float $precision ): float {
+ $sign = $degrees > 0 ? 1 : -1;
+ $reduced = round( abs( $degrees ) / $precision );
+ $expanded = $reduced * $precision;
+
+ return $sign * $expanded;
+ }
+
+ private function getInFloatFormat( float $floatDegrees ): string {
+ $stringDegrees = (string)$floatDegrees;
+
+ if ( $stringDegrees === '-0' ) {
+ return '0';
+ }
+
+ return $stringDegrees;
+ }
+
+ private function getInDecimalDegreeFormat( float $floatDegrees, float $precision ): string {
+ $degreeDigits = $this->getSignificantDigits( 1, $precision );
+ $stringDegrees = $this->formatNumber( $floatDegrees, $degreeDigits );
+
+ return $stringDegrees . $this->options->getOption( self::OPT_DEGREE_SYMBOL );
+ }
+
+ private function getInDegreeMinuteSecondFormat( float $floatDegrees, float $precision ): string {
+ $isNegative = $floatDegrees < 0;
+ $secondDigits = $this->getSignificantDigits( 3600, $precision );
+
+ $seconds = round( abs( $floatDegrees ) * 3600, max( 0, $secondDigits ) );
+ $minutes = (int)( $seconds / 60 );
+ $degrees = (int)( $minutes / 60 );
+
+ $seconds -= $minutes * 60;
+ $minutes -= $degrees * 60;
+
+ $space = $this->getSpacing( self::OPT_SPACE_COORDPARTS );
+ $result = $this->formatNumber( $degrees )
+ . $this->options->getOption( self::OPT_DEGREE_SYMBOL )
+ . $space
+ . $this->formatNumber( $minutes )
+ . $this->options->getOption( self::OPT_MINUTE_SYMBOL )
+ . $space
+ . $this->formatNumber( $seconds, $secondDigits )
+ . $this->options->getOption( self::OPT_SECOND_SYMBOL );
+
+ if ( $isNegative && ( $degrees + $minutes + $seconds ) > 0 ) {
+ $result = '-' . $result;
+ }
+
+ return $result;
+ }
+
+ private function getInDecimalMinuteFormat( float $floatDegrees, float $precision ): string {
+ $isNegative = $floatDegrees < 0;
+ $minuteDigits = $this->getSignificantDigits( 60, $precision );
+
+ $minutes = round( abs( $floatDegrees ) * 60, max( 0, $minuteDigits ) );
+ $degrees = (int)( $minutes / 60 );
+
+ $minutes -= $degrees * 60;
+
+ $space = $this->getSpacing( self::OPT_SPACE_COORDPARTS );
+ $result = $this->formatNumber( $degrees )
+ . $this->options->getOption( self::OPT_DEGREE_SYMBOL )
+ . $space
+ . $this->formatNumber( $minutes, $minuteDigits )
+ . $this->options->getOption( self::OPT_MINUTE_SYMBOL );
+
+ if ( $isNegative && ( $degrees + $minutes ) > 0 ) {
+ $result = '-' . $result;
+ }
+
+ return $result;
+ }
+
+ /**
+ * @param float|int $unitsPerDegree The number of target units per degree
+ * (60 for minutes, 3600 for seconds)
+ * @param float|int $degreePrecision
+ *
+ * @return int The number of digits to show after the decimal point
+ * (resp. before, if the result is negative).
+ */
+ private function getSignificantDigits( float $unitsPerDegree, float $degreePrecision ): int {
+ return (int)ceil( -log10( $unitsPerDegree * $degreePrecision ) );
+ }
+
+ /**
+ * @param float $number
+ * @param int $digits The number of digits after the decimal point.
+ *
+ * @return string
+ */
+ private function formatNumber( float $number, int $digits = 0 ): string {
+ // TODO: use NumberLocalizer
+ return sprintf( '%.' . ( $digits > 0 ? $digits : 0 ) . 'F', $number );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/GlobeMath.php b/www/wiki/vendor/data-values/geo/src/GlobeMath.php
new file mode 100644
index 00000000..984368b8
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/GlobeMath.php
@@ -0,0 +1,116 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo;
+
+use DataValues\Geo\Values\GlobeCoordinateValue;
+use DataValues\Geo\Values\LatLongValue;
+
+/**
+ * Logical and mathematical helper functions for normalizations and calculations with
+ * GlobeCoordinateValue objects.
+ *
+ * @since 0.2
+ *
+ * @license GPL-2.0-or-later
+ * @author Thiemo Kreuz
+ */
+class GlobeMath {
+
+ /**
+ * @todo Move this constant next to GlobeCoordinateValue::GLOBE_EARTH?
+ */
+ public const GLOBE_MOON = 'http://www.wikidata.org/entity/Q405';
+
+ /**
+ * @param string|null $globe IRI of a globe.
+ *
+ * @return string Normalized IRI, defaults to 'http://www.wikidata.org/entity/Q2'.
+ */
+ public function normalizeGlobe( ?string $globe ) {
+ if ( !is_string( $globe ) || $globe === '' ) {
+ return GlobeCoordinateValue::GLOBE_EARTH;
+ }
+
+ return $globe;
+ }
+
+ /**
+ * Normalizes latitude to [-90°..+90°]. Normalizes longitude to [-180°..+180°[ on Earth and
+ * Moon and to [0°..+360°[ on all other globes.
+ * @see http://planetarynames.wr.usgs.gov/TargetCoordinates
+ *
+ * @param GlobeCoordinateValue $value
+ *
+ * @return GlobeCoordinateValue
+ */
+ public function normalizeGlobeCoordinate( GlobeCoordinateValue $value ): GlobeCoordinateValue {
+ return new GlobeCoordinateValue(
+ $this->normalizeGlobeLatLong( $value->getLatLong(), $value->getGlobe() ),
+ $value->getPrecision(),
+ $value->getGlobe()
+ );
+ }
+
+ /**
+ * @param LatLongValue $value
+ * @param string|null $globe
+ *
+ * @return LatLongValue
+ */
+ public function normalizeGlobeLatLong( LatLongValue $value, string $globe = null ): LatLongValue {
+ switch ( $this->normalizeGlobe( $globe ) ) {
+ case GlobeCoordinateValue::GLOBE_EARTH:
+ case self::GLOBE_MOON:
+ $minimumLongitude = -180;
+ break;
+ default:
+ $minimumLongitude = 0;
+ }
+
+ return $this->normalizeLatLong( $value, $minimumLongitude );
+ }
+
+ /**
+ * @param LatLongValue $value
+ * @param float $minimumLongitude
+ *
+ * @return LatLongValue
+ */
+ public function normalizeLatLong( LatLongValue $value, float $minimumLongitude = -180.0 ): LatLongValue {
+ $lat = $value->getLatitude();
+ $lon = $value->getLongitude();
+
+ // Normalize to [-180°..+180°[ on Earth/Moon, [0°..+360°[ on other globes.
+ if ( $lon >= $minimumLongitude + 360 ) {
+ $lon -= 360;
+ } elseif ( $lon < $minimumLongitude ) {
+ $lon += 360;
+ }
+
+ if ( $lat >= 270 ) {
+ // Same side of the globe, on the southern hemisphere.
+ $lat -= 360;
+ } elseif ( $lat <= -270 ) {
+ // Same side of the globe, on the northern hemisphere.
+ $lat += 360;
+ } elseif ( $lat > 90 ) {
+ // Other side of the globe
+ $lat = 180 - $lat;
+ $lon += $lon - 180 >= $minimumLongitude ? -180 : 180;
+ } elseif ( $lat < -90 ) {
+ // Other side of the globe
+ $lat = -180 - $lat;
+ $lon += $lon - 180 >= $minimumLongitude ? -180 : 180;
+ }
+
+ // North/south pole
+ if ( abs( $lat ) === 90.0 ) {
+ $lon = 0;
+ }
+
+ return new LatLongValue( $lat, $lon );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php
new file mode 100644
index 00000000..94b46335
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/DdCoordinateParser.php
@@ -0,0 +1,226 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use DataValues\Geo\Values\LatLongValue;
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+
+/**
+ * Parser for geographical coordinates in Decimal Degree notation.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author H. Snater < mediawiki@snater.com >
+ */
+class DdCoordinateParser extends LatLongParserBase {
+
+ /**
+ * The symbol representing degrees.
+ * @since 0.1
+ */
+ public const OPT_DEGREE_SYMBOL = 'degree';
+
+ /**
+ * @param ParserOptions|null $options
+ */
+ public function __construct( ParserOptions $options = null ) {
+ $options = $options ?: new ParserOptions();
+ $options->defaultOption( self::OPT_DEGREE_SYMBOL, '°' );
+
+ parent::__construct( $options );
+
+ $this->defaultDelimiters = [ $this->getOption( self::OPT_DEGREE_SYMBOL ) ];
+ }
+
+ /**
+ * @see LatLongParserBase::getParsedCoordinate
+ *
+ * @param string $coordinateSegment
+ *
+ * @return float
+ */
+ protected function getParsedCoordinate( string $coordinateSegment ): float {
+ $coordinateSegment = $this->resolveDirection( $coordinateSegment );
+ return $this->parseCoordinate( $coordinateSegment );
+ }
+
+ /**
+ * @see LatLongParserBase::areValidCoordinates
+ *
+ * @param string[] $normalizedCoordinateSegments
+ *
+ * @return bool
+ */
+ protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool {
+ // TODO: Implement localized decimal separator.
+ $baseRegExp = '\d{1,3}(\.\d{1,20})?' . $this->getOption( self::OPT_DEGREE_SYMBOL );
+
+ // Cache whether the coordinates are specified in directional format (a mixture of
+ // directional and non-directional is regarded invalid).
+ $directional = false;
+
+ $match = false;
+
+ foreach ( $normalizedCoordinateSegments as $i => $segment ) {
+ $direction = '('
+ . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')';
+
+ if ( $i === 1 ) {
+ $direction = '('
+ . $this->getOption( self::OPT_EAST_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_WEST_SYMBOL ) . ')';
+ }
+
+ $match = preg_match(
+ '/^(' . $baseRegExp . $direction . '|' . $direction . $baseRegExp . ')$/i',
+ $segment
+ );
+
+ if ( $directional ) {
+ // Directionality is only set after parsing latitude: When the latitude is
+ // is directional, the longitude needs to be as well. Therefore we break here since
+ // checking for directionality is the only check needed for longitude.
+ break;
+ } elseif ( $match ) {
+ // Latitude is directional, no need to check for non-directionality.
+ $directional = true;
+ continue;
+ }
+
+ $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', $segment );
+
+ if ( !$match ) {
+ // Does neither match directional nor non-directional.
+ break;
+ }
+ }
+
+ return ( 1 === $match );
+ }
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param string $value
+ *
+ * @throws ParseException
+ * @return LatLongValue
+ */
+ public function parse( $value ): LatLongValue {
+ if ( !is_string( $value ) ) {
+ throw new ParseException( 'Not a string' );
+ }
+
+ return parent::parse( $this->getNormalizedNotation( $value ) );
+ }
+
+ /**
+ * Returns a normalized version of the coordinate string.
+ *
+ * @param string $coordinates
+ *
+ * @return string
+ */
+ protected function getNormalizedNotation( string $coordinates ): string {
+ $coordinates = str_replace(
+ [ '&#176;', '&deg;' ],
+ $this->getOption( self::OPT_DEGREE_SYMBOL ), $coordinates
+ );
+
+ $coordinates = $this->removeInvalidChars( $coordinates );
+
+ return $coordinates;
+ }
+
+ /**
+ * Returns a string with whitespace, control characters and characters with ASCII values above
+ * 126 removed.
+ *
+ * @see LatLongParserBase::removeInvalidChars
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ protected function removeInvalidChars( string $string ): string {
+ return str_replace( ' ', '', parent::removeInvalidChars( $string ) );
+ }
+
+ /**
+ * Converts a coordinate segment to float representation.
+ *
+ * @param string $coordinateSegment
+ *
+ * @return float
+ */
+ protected function parseCoordinate( string $coordinateSegment ): float {
+ return (float)str_replace(
+ $this->getOption( self::OPT_DEGREE_SYMBOL ),
+ '',
+ $coordinateSegment
+ );
+ }
+
+ /**
+ * @see LatLongParserBase::splitString
+ *
+ * @param string $normalizedCoordinateString
+ *
+ * @return string[]
+ */
+ protected function splitString( string $normalizedCoordinateString ): array {
+ $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+ $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString );
+
+ if ( count( $normalizedCoordinateSegments ) !== 2 ) {
+ // Separator not present within the string, trying to figure out the segments by
+ // splitting after the first direction character or degree symbol:
+ $delimiters = $this->defaultDelimiters;
+
+ $ns = [
+ $this->getOption( self::OPT_NORTH_SYMBOL ),
+ $this->getOption( self::OPT_SOUTH_SYMBOL )
+ ];
+
+ $ew = [
+ $this->getOption( self::OPT_EAST_SYMBOL ),
+ $this->getOption( self::OPT_WEST_SYMBOL )
+ ];
+
+ foreach ( $ns as $delimiter ) {
+ if ( mb_strpos( $normalizedCoordinateString, $delimiter ) === 0 ) {
+ // String starts with "north" or "west" symbol: Separation needs to be done
+ // before the "east" or "west" symbol.
+ $delimiters = array_merge( $ew, $delimiters );
+ break;
+ }
+ }
+
+ if ( count( $delimiters ) !== count( $this->defaultDelimiters ) + 2 ) {
+ $delimiters = array_merge( $ns, $delimiters );
+ }
+
+ foreach ( $delimiters as $delimiter ) {
+ $delimiterPos = mb_strpos( $normalizedCoordinateString, $delimiter );
+ if ( $delimiterPos !== false ) {
+ $adjustPos = ( in_array( $delimiter, $ew ) ) ? 0 : mb_strlen( $delimiter );
+ $normalizedCoordinateSegments = [
+ mb_substr( $normalizedCoordinateString, 0, $delimiterPos + $adjustPos ),
+ mb_substr( $normalizedCoordinateString, $delimiterPos + $adjustPos )
+ ];
+ break;
+ }
+ }
+ }
+
+ return $normalizedCoordinateSegments;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php
new file mode 100644
index 00000000..0dee3115
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/DmCoordinateParser.php
@@ -0,0 +1,167 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+
+/**
+ * Parser for geographical coordinates in Decimal Minute notation.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author H. Snater < mediawiki@snater.com >
+ */
+class DmCoordinateParser extends DdCoordinateParser {
+
+ public const FORMAT_NAME = 'dm-coordinate';
+
+ /**
+ * The symbols representing minutes.
+ * @since 0.1
+ */
+ public const OPT_MINUTE_SYMBOL = 'minute';
+
+ /**
+ * @param ParserOptions|null $options
+ */
+ public function __construct( ParserOptions $options = null ) {
+ $options = $options ?: new ParserOptions();
+ $options->defaultOption( self::OPT_MINUTE_SYMBOL, "'" );
+
+ parent::__construct( $options );
+
+ $this->defaultDelimiters = [ $this->getOption( self::OPT_MINUTE_SYMBOL ) ];
+ }
+
+ /**
+ * @see LatLongParserBase::areValidCoordinates
+ *
+ * @param string[] $normalizedCoordinateSegments
+ *
+ * @return bool
+ */
+ protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool {
+ // At least one coordinate segment needs to have minutes specified.
+ $regExpStrict = '\d{1,3}'
+ . preg_quote( $this->getOption( self::OPT_DEGREE_SYMBOL ) )
+ // TODO: Implement localized decimal separator.
+ . '(\d{1,2}(\.\d{1,20})?'
+ . preg_quote( $this->getOption( self::OPT_MINUTE_SYMBOL ) )
+ . ')';
+ $regExpLoose = $regExpStrict . '?';
+
+ // Cache whether minutes have been detected within the coordinate:
+ $detectedMinute = false;
+
+ // Cache whether the coordinates are specified in directional format (a mixture of
+ // directional and non-directional is regarded invalid).
+ $directional = false;
+
+ foreach ( $normalizedCoordinateSegments as $i => $segment ) {
+ $direction = '('
+ . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')';
+
+ if ( $i === 1 ) {
+ $direction = '('
+ . $this->getOption( self::OPT_EAST_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_WEST_SYMBOL ) . ')';
+ }
+
+ $match = preg_match(
+ '/^(' . $regExpStrict . $direction . '|' . $direction . $regExpStrict . ')$/i',
+ $segment
+ );
+
+ if ( $match ) {
+ $detectedMinute = true;
+ } else {
+ $match = preg_match(
+ '/^(' . $regExpLoose . $direction . '|' . $direction . $regExpLoose . ')$/i',
+ $segment
+ );
+ }
+
+ if ( $match ) {
+ $directional = true;
+ } elseif ( !$directional ) {
+ $match = preg_match( '/^(-)?' . $regExpStrict . '$/i', $segment );
+
+ if ( $match ) {
+ $detectedMinute = true;
+ } else {
+ $match = preg_match( '/^(-)?' . $regExpLoose . '$/i', $segment );
+ }
+ }
+
+ if ( !$match ) {
+ return false;
+ }
+ }
+
+ return $detectedMinute;
+ }
+
+ /**
+ * @see DdCoordinateParser::getNormalizedNotation
+ *
+ * @param string $coordinates
+ *
+ * @return string
+ */
+ protected function getNormalizedNotation( string $coordinates ): string {
+ $minute = $this->getOption( self::OPT_MINUTE_SYMBOL );
+
+ $coordinates = str_replace( [ '&#8242;', '&prime;', '´', '′' ], $minute, $coordinates );
+
+ $coordinates = parent::getNormalizedNotation( $coordinates );
+
+ $coordinates = $this->removeInvalidChars( $coordinates );
+
+ return $coordinates;
+ }
+
+ /**
+ * @see DdCoordinateParser::parseCoordinate
+ *
+ * @param string $coordinateSegment
+ *
+ * @return float
+ */
+ protected function parseCoordinate( string $coordinateSegment ): float {
+ $isNegative = substr( $coordinateSegment, 0, 1 ) === '-';
+
+ if ( $isNegative ) {
+ $coordinateSegment = substr( $coordinateSegment, 1 );
+ }
+
+ $degreeSymbol = $this->getOption( self::OPT_DEGREE_SYMBOL );
+ $exploded = explode( $degreeSymbol, $coordinateSegment );
+
+ if ( count( $exploded ) !== 2 ) {
+ throw new ParseException(
+ 'Unable to explode coordinate segment by degree symbol (' . $degreeSymbol . ')',
+ $coordinateSegment,
+ self::FORMAT_NAME
+ );
+ }
+
+ list( $degrees, $minutes ) = $exploded;
+
+ $minutes = substr( $minutes, 0, -1 );
+
+ $coordinateSegment = $degrees + $minutes / 60;
+
+ if ( $isNegative ) {
+ $coordinateSegment *= -1;
+ }
+
+ return (float)$coordinateSegment;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php
new file mode 100644
index 00000000..c6fc079a
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/DmsCoordinateParser.php
@@ -0,0 +1,198 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+
+/**
+ * Parser for geographical coordinates in Degree Minute Second notation.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author H. Snater < mediawiki@snater.com >
+ */
+class DmsCoordinateParser extends DmCoordinateParser {
+
+ public const FORMAT_NAME = 'dms-coordinate';
+
+ /**
+ * The symbol representing seconds.
+ * @since 0.1
+ */
+ public const OPT_SECOND_SYMBOL = 'second';
+
+ /**
+ * @param ParserOptions|null $options
+ */
+ public function __construct( ParserOptions $options = null ) {
+ $options = $options ?: new ParserOptions();
+ $options->defaultOption( self::OPT_SECOND_SYMBOL, '"' );
+
+ parent::__construct( $options );
+
+ $this->defaultDelimiters = [ $this->getOption( self::OPT_SECOND_SYMBOL ) ];
+ }
+
+ /**
+ * @see LatLongParserBase::areValidCoordinates
+ *
+ * @param string[] $normalizedCoordinateSegments
+ *
+ * @return bool
+ */
+ protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool {
+ // At least one coordinate segment needs to have seconds specified (which additionally
+ // requires minutes to be specified).
+ $regExpLoose = '(\d{1,3}'
+ . preg_quote( $this->getOption( self::OPT_DEGREE_SYMBOL ) )
+ . ')(\d{1,2}'
+ . preg_quote( $this->getOption( self::OPT_MINUTE_SYMBOL ) )
+ . ')?((\d{1,2}'
+ . preg_quote( $this->getOption( self::OPT_SECOND_SYMBOL ) )
+ // TODO: Implement localized decimal separator.
+ . ')?|(\d{1,2}\.\d{1,20}'
+ . preg_quote( $this->getOption( self::OPT_SECOND_SYMBOL ) )
+ . ')?)';
+ $regExpStrict = str_replace( '?', '', $regExpLoose );
+
+ // Cache whether seconds have been detected within the coordinate:
+ $detectedSecond = false;
+
+ // Cache whether the coordinates are specified in directional format (a mixture of
+ // directional and non-directional is regarded invalid).
+ $directional = false;
+
+ foreach ( $normalizedCoordinateSegments as $i => $segment ) {
+ $direction = '('
+ . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')';
+
+ if ( $i === 1 ) {
+ $direction = '('
+ . $this->getOption( self::OPT_EAST_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_WEST_SYMBOL ) . ')';
+ }
+
+ $match = preg_match(
+ '/^(' . $regExpStrict . $direction . '|' . $direction . $regExpStrict . ')$/i',
+ $segment
+ );
+
+ if ( $match ) {
+ $detectedSecond = true;
+ } else {
+ $match = preg_match(
+ '/^(' . $regExpLoose . $direction . '|' . $direction . $regExpLoose . ')$/i',
+ $segment
+ );
+ }
+
+ if ( $match ) {
+ $directional = true;
+ } elseif ( !$directional ) {
+ $match = preg_match( '/^(-)?' . $regExpStrict . '$/i', $segment );
+
+ if ( $match ) {
+ $detectedSecond = true;
+ } else {
+ $match = preg_match( '/^(-)?' . $regExpLoose . '$/i', $segment );
+ }
+ }
+
+ if ( !$match ) {
+ return false;
+ }
+ }
+
+ return $detectedSecond;
+ }
+
+ /**
+ * @see DdCoordinateParser::getNormalizedNotation
+ *
+ * @param string $coordinates
+ *
+ * @return string
+ */
+ protected function getNormalizedNotation( string $coordinates ): string {
+ $second = $this->getOption( self::OPT_SECOND_SYMBOL );
+ $minute = $this->getOption( self::OPT_MINUTE_SYMBOL );
+
+ $coordinates = str_replace(
+ [ '&#8243;', '&Prime;', $minute . $minute, '´´', '′′', '″' ],
+ $second,
+ $coordinates
+ );
+ $coordinates = str_replace( [ '&acute;', '&#180;' ], $second, $coordinates );
+
+ $coordinates = parent::getNormalizedNotation( $coordinates );
+
+ $coordinates = $this->removeInvalidChars( $coordinates );
+
+ return $coordinates;
+ }
+
+ /**
+ * @see DdCoordinateParser::parseCoordinate
+ *
+ * @param string $coordinateSegment
+ *
+ * @return float
+ */
+ protected function parseCoordinate( string $coordinateSegment ): float {
+ $isNegative = mb_substr( $coordinateSegment, 0, 1 ) === '-';
+
+ if ( $isNegative ) {
+ $coordinateSegment = mb_substr( $coordinateSegment, 1 );
+ }
+
+ $degreeSymbol = $this->getOption( self::OPT_DEGREE_SYMBOL );
+ $degreePosition = mb_strpos( $coordinateSegment, $degreeSymbol );
+
+ if ( $degreePosition === false ) {
+ throw new ParseException(
+ 'Did not find degree symbol (' . $degreeSymbol . ')',
+ $coordinateSegment,
+ self::FORMAT_NAME
+ );
+ }
+
+ $degrees = (float)mb_substr( $coordinateSegment, 0, $degreePosition );
+
+ $minutePosition = mb_strpos( $coordinateSegment, $this->getOption( self::OPT_MINUTE_SYMBOL ) );
+
+ if ( $minutePosition === false ) {
+ $minutes = 0;
+ } else {
+ $degSignLength = mb_strlen( $this->getOption( self::OPT_DEGREE_SYMBOL ) );
+ $minuteLength = $minutePosition - $degreePosition - $degSignLength;
+ $minutes = (float)mb_substr( $coordinateSegment, $degreePosition + $degSignLength, $minuteLength );
+ }
+
+ $secondPosition = mb_strpos( $coordinateSegment, $this->getOption( self::OPT_SECOND_SYMBOL ) );
+
+ if ( $secondPosition === false ) {
+ $seconds = 0;
+ } else {
+ $seconds = (float)mb_substr(
+ $coordinateSegment,
+ ( $minutePosition === false ? $degreePosition : $minutePosition ) + 1,
+ -1
+ );
+ }
+
+ $coordinateSegment = $degrees + ( $minutes + $seconds / 60 ) / 60;
+
+ if ( $isNegative ) {
+ $coordinateSegment *= -1;
+ }
+
+ return (float)$coordinateSegment;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php
new file mode 100644
index 00000000..3b57bb44
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/FloatCoordinateParser.php
@@ -0,0 +1,136 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use ValueParsers\ParseException;
+
+/**
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author H. Snater < mediawiki@snater.com >
+ */
+class FloatCoordinateParser extends LatLongParserBase {
+
+ public const FORMAT_NAME = 'float-coordinate';
+
+ /**
+ * @see LatLongParserBase::getParsedCoordinate
+ *
+ * @param string $coordinateSegment
+ *
+ * @return float
+ */
+ protected function getParsedCoordinate( string $coordinateSegment ): float {
+ return (float)$this->resolveDirection( str_replace( ' ', '', $coordinateSegment ) );
+ }
+
+ /**
+ * @see LatLongParserBase::areValidCoordinates
+ *
+ * @param string[] $normalizedCoordinateSegments
+ *
+ * @return bool
+ */
+ protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool {
+ // TODO: Implement localized decimal separator.
+ $baseRegExp = '\d{1,3}(\.\d{1,20})?';
+
+ // Cache whether the coordinates are specified in directional format (a mixture of
+ // directional and non-directional is regarded invalid).
+ $directional = false;
+
+ $match = false;
+
+ foreach ( $normalizedCoordinateSegments as $i => $segment ) {
+ $segment = str_replace( ' ', '', $segment );
+
+ $direction = '('
+ . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_SOUTH_SYMBOL ) . ')';
+
+ if ( $i === 1 ) {
+ $direction = '('
+ . $this->getOption( self::OPT_EAST_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_WEST_SYMBOL ) . ')';
+ }
+
+ $match = preg_match(
+ '/^(' . $baseRegExp . $direction . '|' . $direction . $baseRegExp . ')$/i',
+ $segment
+ );
+
+ if ( $directional && !$match ) {
+ // Latitude is directional, longitude not.
+ break;
+ } elseif ( $match ) {
+ continue;
+ }
+
+ $match = preg_match( '/^(-)?' . $baseRegExp . '$/i', $segment );
+
+ if ( !$match ) {
+ // Does neither match directional nor non-directional.
+ break;
+ }
+ }
+
+ return ( 1 === $match );
+ }
+
+ /**
+ * @see LatLongParserBase::splitString
+ *
+ * @param string $normalizedCoordinateString
+ *
+ * @throws ParseException if unable to split input string into two segments
+ * @return string[]
+ */
+ protected function splitString( string $normalizedCoordinateString ): array {
+ $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+ $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString );
+
+ if ( count( $normalizedCoordinateSegments ) !== 2 ) {
+ // Separator not present within the string, trying to figure out the segments by
+ // splitting at the the first SPACE after the first direction character or digit:
+ $numberRegEx = '-?\d{1,3}(\.\d{1,20})?';
+
+ $ns = '('
+ . $this->getOption( self::OPT_NORTH_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_SOUTH_SYMBOL ) .')';
+
+ $latitudeRegEx = '(' . $ns . '\s*)?' . $numberRegEx . '(\s*' . $ns . ')?';
+
+ $ew = '('
+ . $this->getOption( self::OPT_EAST_SYMBOL ) . '|'
+ . $this->getOption( self::OPT_WEST_SYMBOL ) .')';
+
+ $longitudeRegEx = '(' . $ew . '\s*)?' . $numberRegEx . '(\s*' . $ew . ')?';
+
+ $match = preg_match(
+ '/^(' . $latitudeRegEx . ') (' . $longitudeRegEx . ')$/i',
+ $normalizedCoordinateString,
+ $matches
+ );
+
+ if ( $match ) {
+ $normalizedCoordinateSegments = [ $matches[1], $matches[7] ];
+ }
+ }
+
+ if ( count( $normalizedCoordinateSegments ) !== 2 ) {
+ throw new ParseException(
+ 'Unable to split input into two coordinate segments',
+ $normalizedCoordinateString,
+ self::FORMAT_NAME
+ );
+ }
+
+ return $normalizedCoordinateSegments;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php
new file mode 100644
index 00000000..15c1503d
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/GlobeCoordinateParser.php
@@ -0,0 +1,138 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use DataValues\Geo\Values\GlobeCoordinateValue;
+use DataValues\Geo\Values\LatLongValue;
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+use ValueParsers\ValueParser;
+
+/**
+ * Extends the LatLongParser by adding precision detection support.
+ *
+ * The object that gets constructed is a GlobeCoordinateValue rather then a LatLongValue.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author H. Snater < mediawiki@snater.com >
+ * @author Thiemo Kreuz
+ */
+class GlobeCoordinateParser implements ValueParser {
+
+ public const FORMAT_NAME = 'globe-coordinate';
+
+ /**
+ * Option specifying the globe. Should be a string containing a Wikidata concept URI. Defaults
+ * to Earth.
+ */
+ public const OPT_GLOBE = 'globe';
+
+ private $options;
+
+ public function __construct( ParserOptions $options = null ) {
+ $this->options = $options ?: new ParserOptions();
+
+ $this->options->defaultOption( ValueParser::OPT_LANG, 'en' );
+ $this->options->defaultOption( self::OPT_GLOBE, 'http://www.wikidata.org/entity/Q2' );
+ }
+
+ /**
+ * @see StringValueParser::stringParse
+ *
+ * @param string $value
+ *
+ * @throws ParseException
+ * @return GlobeCoordinateValue
+ */
+ public function parse( $value ): GlobeCoordinateValue {
+ foreach ( $this->getParsers() as $precisionDetector => $parser ) {
+ try {
+ $latLong = $parser->parse( $value );
+
+ return new GlobeCoordinateValue(
+ new LatLongValue(
+ $latLong->getLatitude(),
+ $latLong->getLongitude()
+ ),
+ $this->detectPrecision( $latLong, $precisionDetector ),
+ $this->options->getOption( self::OPT_GLOBE )
+ );
+ } catch ( ParseException $parseException ) {
+ continue;
+ }
+ }
+
+ throw new ParseException(
+ 'The format of the coordinate could not be determined.',
+ $value,
+ self::FORMAT_NAME
+ );
+ }
+
+ private function detectPrecision( LatLongValue $latLong, string $precisionDetector ): float {
+ if ( $this->options->hasOption( 'precision' ) ) {
+ return $this->options->getOption( 'precision' );
+ }
+
+ return min(
+ call_user_func( [ $this, $precisionDetector ], $latLong->getLatitude() ),
+ call_user_func( [ $this, $precisionDetector ], $latLong->getLongitude() )
+ );
+ }
+
+ /**
+ * @return ValueParser[]
+ */
+ private function getParsers(): array {
+ $parsers = [];
+
+ $parsers['detectFloatPrecision'] = new FloatCoordinateParser( $this->options );
+ $parsers['detectDmsPrecision'] = new DmsCoordinateParser( $this->options );
+ $parsers['detectDmPrecision'] = new DmCoordinateParser( $this->options );
+ $parsers['detectDdPrecision'] = new DdCoordinateParser( $this->options );
+
+ return $parsers;
+ }
+
+ private function detectDdPrecision( float $degree ): float {
+ return $this->detectFloatPrecision( $degree );
+ }
+
+ private function detectDmPrecision( float $degree ): float {
+ $minutes = $degree * 60;
+ $split = explode( '.', (string)round( $minutes, 6 ) );
+
+ if ( isset( $split[1] ) ) {
+ return $this->detectDmsPrecision( $degree );
+ }
+
+ return 1 / 60;
+ }
+
+ private function detectDmsPrecision( float $degree ): float {
+ $seconds = $degree * 3600;
+ $split = explode( '.', (string)round( $seconds, 4 ) );
+
+ if ( isset( $split[1] ) ) {
+ return pow( 10, -strlen( $split[1] ) ) / 3600;
+ }
+
+ return 1 / 3600;
+ }
+
+ private function detectFloatPrecision( float $degree ): float {
+ $split = explode( '.', (string)round( $degree, 8 ) );
+
+ if ( isset( $split[1] ) ) {
+ return pow( 10, -strlen( $split[1] ) );
+ }
+
+ return 1;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php
new file mode 100644
index 00000000..b83129b1
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParser.php
@@ -0,0 +1,108 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use DataValues\Geo\Values\LatLongValue;
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+use ValueParsers\ValueParser;
+
+/**
+ * ValueParser that parses the string representation of a geographical coordinate.
+ *
+ * The resulting objects are of type @see LatLongValue.
+ *
+ * Supports the following notations:
+ * - Degree minute second
+ * - Decimal degrees
+ * - Decimal minutes
+ * - Float
+ *
+ * And for all these notations direction can be indicated either with
+ * + and - or with N/E/S/W, the later depending on the set options.
+ *
+ * The delimiter between latitude and longitude can be set in the options.
+ * So can the symbols used for degrees, minutes and seconds.
+ *
+ * Some code in this class has been borrowed from the
+ * MapsCoordinateParser class of the Maps extension for MediaWiki.
+ *
+ * @since 0.1, name changed in 2.0
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class LatLongParser implements ValueParser {
+
+ public const TYPE_FLOAT = 'float';
+ public const TYPE_DMS = 'dms';
+ public const TYPE_DM = 'dm';
+ public const TYPE_DD = 'dd';
+
+ /**
+ * The symbols representing the different directions for usage in directional notation.
+ */
+ public const OPT_NORTH_SYMBOL = 'north';
+ public const OPT_EAST_SYMBOL = 'east';
+ public const OPT_SOUTH_SYMBOL = 'south';
+ public const OPT_WEST_SYMBOL = 'west';
+
+ /**
+ * The symbols representing degrees, minutes and seconds.
+ */
+ public const OPT_DEGREE_SYMBOL = 'degree';
+ public const OPT_MINUTE_SYMBOL = 'minute';
+ public const OPT_SECOND_SYMBOL = 'second';
+
+ /**
+ * The symbol to use as separator between latitude and longitude.
+ */
+ public const OPT_SEPARATOR_SYMBOL = 'separator';
+
+ /**
+ * @var ParserOptions
+ */
+ private $options;
+
+ public function __construct( ParserOptions $options = null ) {
+ $this->options = $options ?: new ParserOptions();
+ $this->options->defaultOption( ValueParser::OPT_LANG, 'en' );
+ }
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param string $value
+ *
+ * @throws ParseException
+ * @return LatLongValue
+ */
+ public function parse( $value ): LatLongValue {
+ foreach ( $this->getParsers() as $parser ) {
+ try {
+ return $parser->parse( $value );
+ } catch ( ParseException $ex ) {
+ continue;
+ }
+ }
+
+ throw new ParseException( 'The format of the coordinate could not be determined. Parsing failed.' );
+ }
+
+ /**
+ * @return LatLongParserBase[]
+ */
+ private function getParsers(): array {
+ $parsers = [];
+
+ $parsers[] = new FloatCoordinateParser( $this->options );
+ $parsers[] = new DmsCoordinateParser( $this->options );
+ $parsers[] = new DmCoordinateParser( $this->options );
+ $parsers[] = new DdCoordinateParser( $this->options );
+
+ return $parsers;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php
new file mode 100644
index 00000000..258f9e92
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Parsers/LatLongParserBase.php
@@ -0,0 +1,248 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Parsers;
+
+use DataValues\Geo\Values\LatLongValue;
+use ValueParsers\ParseException;
+use ValueParsers\ParserOptions;
+use ValueParsers\ValueParser;
+
+/**
+ * @since 0.1, renamed in 2.0
+ *
+ * @license GPL-2.0-or-later
+ * @author H. Snater < mediawiki@snater.com >
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class LatLongParserBase implements ValueParser {
+
+ public const FORMAT_NAME = 'geo-coordinate';
+
+ /**
+ * The symbols representing the different directions for usage in directional notation.
+ */
+ public const OPT_NORTH_SYMBOL = 'north';
+ public const OPT_EAST_SYMBOL = 'east';
+ public const OPT_SOUTH_SYMBOL = 'south';
+ public const OPT_WEST_SYMBOL = 'west';
+
+ /**
+ * The symbol to use as separator between latitude and longitude.
+ */
+ public const OPT_SEPARATOR_SYMBOL = 'separator';
+
+ /**
+ * Delimiters used to split a coordinate string when unable to split by using the separator.
+ * @var string[]
+ */
+ protected $defaultDelimiters;
+
+ /**
+ * @var ParserOptions
+ */
+ private $options;
+
+ public function __construct( ParserOptions $options = null ) {
+ $this->options = $options ?: new ParserOptions();
+
+ $this->options->defaultOption( ValueParser::OPT_LANG, 'en' );
+
+ $this->options->defaultOption( self::OPT_NORTH_SYMBOL, 'N' );
+ $this->options->defaultOption( self::OPT_EAST_SYMBOL, 'E' );
+ $this->options->defaultOption( self::OPT_SOUTH_SYMBOL, 'S' );
+ $this->options->defaultOption( self::OPT_WEST_SYMBOL, 'W' );
+
+ $this->options->defaultOption( self::OPT_SEPARATOR_SYMBOL, ',' );
+ }
+
+ /**
+ * Parses a single coordinate segment (either latitude or longitude) and returns it as a float.
+ *
+ * @param string $coordinateSegment
+ *
+ * @throws ParseException
+ * @return float
+ */
+ abstract protected function getParsedCoordinate( string $coordinateSegment ): float;
+
+ /**
+ * Returns whether a coordinate split into its two segments is in the representation expected by
+ * this parser.
+ *
+ * @param string[] $normalizedCoordinateSegments
+ *
+ * @return bool
+ */
+ abstract protected function areValidCoordinates( array $normalizedCoordinateSegments ): bool;
+
+ /**
+ * @see ValueParser::parse
+ *
+ * @param string $value
+ *
+ * @throws ParseException
+ * @return LatLongValue
+ */
+ public function parse( $value ): LatLongValue {
+ if ( !is_string( $value ) ) {
+ throw new ParseException( 'Not a string' );
+ }
+
+ $rawValue = $value;
+
+ $value = $this->removeInvalidChars( $value );
+
+ $normalizedCoordinateSegments = $this->splitString( $value );
+
+ if ( !$this->areValidCoordinates( $normalizedCoordinateSegments ) ) {
+ throw new ParseException( 'Not a valid geographical coordinate', $rawValue, static::FORMAT_NAME );
+ }
+
+ list( $latitude, $longitude ) = $normalizedCoordinateSegments;
+
+ return new LatLongValue(
+ $this->getParsedCoordinate( $latitude ),
+ $this->getParsedCoordinate( $longitude )
+ );
+ }
+
+ /**
+ * Returns a string trimmed and with control characters and characters with ASCII values above
+ * 126 removed. SPACE characters within the string are not removed to retain the option to split
+ * the string using that character.
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ protected function removeInvalidChars( string $string ): string {
+ $filtered = [];
+
+ foreach ( str_split( $string ) as $character ) {
+ $asciiValue = ord( $character );
+
+ if (
+ ( $asciiValue >= 32 && $asciiValue < 127 )
+ || $asciiValue == 194
+ || $asciiValue == 176
+ ) {
+ $filtered[] = $character;
+ }
+ }
+
+ return trim( implode( '', $filtered ) );
+ }
+
+ /**
+ * Splits a string into two strings using the separator specified in the options. If the string
+ * could not be split using the separator, the method will try to split the string by analyzing
+ * the used symbols. If the string could not be split into two parts, an empty array is
+ * returned.
+ *
+ * @param string $normalizedCoordinateString
+ *
+ * @throws ParseException if unable to split input string into two segments
+ * @return string[]
+ */
+ protected function splitString( string $normalizedCoordinateString ): array {
+ $separator = $this->getOption( self::OPT_SEPARATOR_SYMBOL );
+
+ $normalizedCoordinateSegments = explode( $separator, $normalizedCoordinateString );
+
+ if ( count( $normalizedCoordinateSegments ) !== 2 ) {
+ // Separator not present within the string, trying to figure out the segments by
+ // splitting after the first direction character or degree symbol:
+ $delimiters = $this->defaultDelimiters;
+
+ $ns = [
+ $this->getOption( self::OPT_NORTH_SYMBOL ),
+ $this->getOption( self::OPT_SOUTH_SYMBOL )
+ ];
+
+ $ew = [
+ $this->getOption( self::OPT_EAST_SYMBOL ),
+ $this->getOption( self::OPT_WEST_SYMBOL )
+ ];
+
+ foreach ( $ns as $delimiter ) {
+ if ( mb_strpos( $normalizedCoordinateString, $delimiter ) === 0 ) {
+ // String starts with "north" or "west" symbol: Separation needs to be done
+ // before the "east" or "west" symbol.
+ $delimiters = array_merge( $ew, $delimiters );
+ break;
+ }
+ }
+
+ if ( count( $delimiters ) !== count( $this->defaultDelimiters ) + 2 ) {
+ $delimiters = array_merge( $ns, $delimiters );
+ }
+
+ foreach ( $delimiters as $delimiter ) {
+ $delimiterPos = mb_strpos( $normalizedCoordinateString, $delimiter );
+ if ( $delimiterPos !== false ) {
+ $adjustPos = ( in_array( $delimiter, $ew ) ) ? 0 : mb_strlen( $delimiter );
+ $normalizedCoordinateSegments = [
+ mb_substr( $normalizedCoordinateString, 0, $delimiterPos + $adjustPos ),
+ mb_substr( $normalizedCoordinateString, $delimiterPos + $adjustPos )
+ ];
+ break;
+ }
+ }
+ }
+
+ if ( count( $normalizedCoordinateSegments ) !== 2 ) {
+ throw new ParseException( __CLASS__ . ': Unable to split string '
+ . $normalizedCoordinateString . ' into two coordinate segments' );
+ }
+
+ return $normalizedCoordinateSegments;
+ }
+
+ /**
+ * Turns directional notation (N/E/S/W) of a single coordinate into non-directional notation
+ * (+/-).
+ * This method assumes there are no preceding or tailing spaces.
+ *
+ * @param string $coordinateSegment
+ *
+ * @return string
+ */
+ protected function resolveDirection( string $coordinateSegment ): string {
+ $n = $this->getOption( self::OPT_NORTH_SYMBOL );
+ $e = $this->getOption( self::OPT_EAST_SYMBOL );
+ $s = $this->getOption( self::OPT_SOUTH_SYMBOL );
+ $w = $this->getOption( self::OPT_WEST_SYMBOL );
+
+ // If there is a direction indicator, remove it, and prepend a minus sign for south and west
+ // directions. If there is no direction indicator, the coordinate is already non-directional
+ // and no work is required.
+ foreach ( [ $n, $e, $s, $w ] as $direction ) {
+ // The coordinate segment may either start or end with a direction symbol.
+ preg_match(
+ '/^(' . $direction . '|)([^' . $direction . ']+)(' . $direction . '|)$/i',
+ $coordinateSegment,
+ $matches
+ );
+
+ if ( $matches[1] !== '' || $matches[3] !== '' ) {
+ $coordinateSegment = $matches[2];
+
+ if ( in_array( $direction, [ $s, $w ] ) ) {
+ $coordinateSegment = '-' . $coordinateSegment;
+ }
+
+ return $coordinateSegment;
+ }
+ }
+
+ // Coordinate segment does not include a direction symbol.
+ return $coordinateSegment;
+ }
+
+ protected function getOption( string $optionName ) {
+ return $this->options->getOption( $optionName );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php b/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php
new file mode 100644
index 00000000..d5fd581f
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Values/GlobeCoordinateValue.php
@@ -0,0 +1,220 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Values;
+
+use DataValues\DataValue;
+use DataValues\IllegalValueException;
+use InvalidArgumentException;
+
+/**
+ * Value Object representing a latitude-longitude pair with a certain precision on a certain globe.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Thiemo Kreuz
+ */
+class GlobeCoordinateValue implements DataValue {
+
+ private $latLong;
+
+ /**
+ * @var float|null
+ */
+ private $precision;
+
+ /**
+ * IRI of the globe on which the location resides.
+ *
+ * @var string
+ */
+ private $globe;
+
+ /**
+ * Wikidata concept URI for the Earth. Used as default value when no other globe was specified.
+ */
+ public const GLOBE_EARTH = 'http://www.wikidata.org/entity/Q2';
+
+ /**
+ * @param LatLongValue $latLong
+ * @param float|int|null $precision in degrees, e.g. 0.01.
+ * @param string|null $globe IRI, defaults to 'http://www.wikidata.org/entity/Q2'.
+ *
+ * @throws IllegalValueException
+ */
+ public function __construct( LatLongValue $latLong, float $precision = null, string $globe = null ) {
+ $this->assertIsPrecision( $precision );
+
+ if ( $globe === null ) {
+ $globe = self::GLOBE_EARTH;
+ } elseif ( $globe === '' ) {
+ throw new IllegalValueException( '$globe must be a non-empty string or null' );
+ }
+
+ $this->latLong = $latLong;
+ $this->precision = $precision;
+ $this->globe = $globe;
+ }
+
+ private function assertIsPrecision( ?float $precision ) {
+ if ( is_float( $precision ) && ( $precision < -360 || $precision > 360 ) ) {
+ throw new IllegalValueException( '$precision needs to be between -360 and 360' );
+ }
+ }
+
+ public function getLatLong(): LatLongValue {
+ return $this->latLong;
+ }
+
+ /**
+ * Returns the precision of the coordinate in degrees, e.g. 0.01.
+ */
+ public function getPrecision(): ?float {
+ return $this->precision;
+ }
+
+ /**
+ * Returns the IRI of the globe on which the location resides.
+ */
+ public function getGlobe(): string {
+ return $this->globe;
+ }
+
+ public function getLatitude(): float {
+ return $this->latLong->getLatitude();
+ }
+
+ public function getLongitude(): float {
+ return $this->latLong->getLongitude();
+ }
+
+ /**
+ * @see \Comparable::equals
+ */
+ public function equals( $target ): bool {
+ return $target instanceof self
+ && $this->latLong->equals( $target->latLong )
+ && $this->precision === $target->precision
+ && $this->globe === $target->globe;
+ }
+
+ public function getCopy(): self {
+ return new self(
+ $this->latLong,
+ $this->precision,
+ $this->globe
+ );
+ }
+
+ /**
+ * @see Hashable::getHash
+ *
+ * @since 2.0
+ */
+ public function getHash(): string {
+ return md5(
+ $this->latLong->getLatitude() . '|'
+ . $this->latLong->getLongitude() . '|'
+ . $this->precision . '|'
+ . $this->globe
+ );
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize(): string {
+ return json_encode( array_values( $this->getArrayValue() ) );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ *
+ * @throws InvalidArgumentException
+ */
+ public function unserialize( $value ) {
+ list( $latitude, $longitude, $altitude, $precision, $globe ) = json_decode( $value );
+ $this->__construct( new LatLongValue( $latitude, $longitude ), $precision, $globe );
+ }
+
+ /**
+ * @see DataValue::getType
+ */
+ public static function getType(): string {
+ return 'globecoordinate';
+ }
+
+ /**
+ * @see DataValue::getSortKey
+ */
+ public function getSortKey(): float {
+ return $this->getLatitude();
+ }
+
+ /**
+ * @see DataValue::getValue
+ */
+ public function getValue(): self {
+ return $this;
+ }
+
+ /**
+ * @see DataValue::getArrayValue
+ */
+ public function getArrayValue(): array {
+ return [
+ 'latitude' => $this->latLong->getLatitude(),
+ 'longitude' => $this->latLong->getLongitude(),
+
+ // The altitude field is no longer used in this class.
+ // It is kept here for compatibility reasons.
+ 'altitude' => null,
+
+ 'precision' => $this->precision,
+ 'globe' => $this->globe,
+ ];
+ }
+
+ public function toArray(): array {
+ return [
+ 'value' => $this->getArrayValue(),
+ 'type' => $this->getType(),
+ ];
+ }
+
+ /**
+ * Constructs a new instance from the provided array. Round-trips with @see getArrayValue.
+ *
+ * @throws InvalidArgumentException
+ */
+ public static function newFromArray( $data ): self {
+ if ( !is_array( $data ) ) {
+ throw new IllegalValueException( 'array expected' );
+ }
+
+ if ( !array_key_exists( 'latitude', $data ) ) {
+ throw new IllegalValueException( 'latitude field required' );
+ }
+
+ if ( !array_key_exists( 'longitude', $data ) ) {
+ throw new IllegalValueException( 'longitude field required' );
+ }
+
+ return new static(
+ new LatLongValue(
+ $data['latitude'],
+ $data['longitude']
+ ),
+ ( isset( $data['precision'] ) ) ? $data['precision'] : null,
+ ( isset( $data['globe'] ) ) ? $data['globe'] : null
+ );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php b/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php
new file mode 100644
index 00000000..e3a23c6c
--- /dev/null
+++ b/www/wiki/vendor/data-values/geo/src/Values/LatLongValue.php
@@ -0,0 +1,162 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace DataValues\Geo\Values;
+
+use DataValues\DataValue;
+use DataValues\IllegalValueException;
+use InvalidArgumentException;
+
+/**
+ * Value Object representing a geographical point.
+ *
+ * Latitude is specified in degrees within the range [-360, 360].
+ * Longitude is specified in degrees within the range [-360, 360].
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class LatLongValue implements DataValue {
+
+ private $latitude;
+ private $longitude;
+
+ /**
+ * @param float|int $latitude Latitude in degrees within the range [-360, 360]
+ * @param float|int $longitude Longitude in degrees within the range [-360, 360]
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct( float $latitude, float $longitude ) {
+ $this->assertIsLatitude( $latitude );
+ $this->assertIsLongitude( $longitude );
+
+ $this->latitude = $latitude;
+ $this->longitude = $longitude;
+ }
+
+ private function assertIsLatitude( float $latitude ) {
+ if ( $latitude < -360 || $latitude > 360 ) {
+ throw new InvalidArgumentException( 'Latitude needs to be between -360 and 360' );
+ }
+ }
+
+ private function assertIsLongitude( float $longitude ) {
+ if ( $longitude < -360 || $longitude > 360 ) {
+ throw new InvalidArgumentException( 'Longitude needs to be between -360 and 360' );
+ }
+ }
+
+ public function getLatitude(): float {
+ return $this->latitude;
+ }
+
+ public function getLongitude(): float {
+ return $this->longitude;
+ }
+
+ /**
+ * @see \Comparable::equals
+ */
+ public function equals( $target ): bool {
+ return $target instanceof self
+ && $this->latitude === $target->latitude
+ && $this->longitude === $target->longitude;
+ }
+
+ /**
+ * @see \Hashable::getHash
+ */
+ public function getHash(): string {
+ return md5( serialize( $this ) );
+ }
+
+ public function getCopy(): self {
+ return new self( $this->latitude, $this->longitude );
+ }
+
+ /**
+ * @see Serializable::serialize
+ *
+ * @return string
+ */
+ public function serialize(): string {
+ $data = [
+ $this->latitude,
+ $this->longitude
+ ];
+
+ return implode( '|', $data );
+ }
+
+ /**
+ * @see Serializable::unserialize
+ *
+ * @param string $value
+ *
+ * @throws InvalidArgumentException
+ */
+ public function unserialize( $value ) {
+ $data = explode( '|', $value, 2 );
+
+ if ( count( $data ) < 2 ) {
+ throw new InvalidArgumentException( 'Invalid serialization provided in ' . __METHOD__ );
+ }
+
+ $this->__construct( (float)$data[0], (float)$data[1] );
+ }
+
+ public static function getType(): string {
+ return 'geocoordinate';
+ }
+
+ public function getSortKey(): float {
+ return $this->latitude;
+ }
+
+ public function getValue(): self {
+ return $this;
+ }
+
+ /**
+ * @return float[]
+ */
+ public function getArrayValue(): array {
+ return [
+ 'latitude' => $this->latitude,
+ 'longitude' => $this->longitude
+ ];
+ }
+
+ /**
+ * Constructs a new instance from the provided array. Round-trips with @see getArrayValue.
+ *
+ * @throws InvalidArgumentException
+ */
+ public static function newFromArray( $data ): self {
+ if ( !is_array( $data ) ) {
+ throw new IllegalValueException( 'array expected' );
+ }
+
+ if ( !array_key_exists( 'latitude', $data ) ) {
+ throw new IllegalValueException( 'latitude field required' );
+ }
+
+ if ( !array_key_exists( 'longitude', $data ) ) {
+ throw new IllegalValueException( 'longitude field required' );
+ }
+
+ return new static( $data['latitude'], $data['longitude'] );
+ }
+
+ public function toArray(): array {
+ return [
+ 'value' => $this->getArrayValue(),
+ 'type' => $this->getType(),
+ ];
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/COPYING b/www/wiki/vendor/data-values/interfaces/COPYING
new file mode 100644
index 00000000..ebba08a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text contained in
+said file overrides any license information contained in directories of smaller depth.
+Alternative licenses are typically used for software that is provided by external
+parties, and merely packaged with this software for convenience.
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
diff --git a/www/wiki/vendor/data-values/interfaces/Interfaces.php b/www/wiki/vendor/data-values/interfaces/Interfaces.php
new file mode 100644
index 00000000..d3495021
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/Interfaces.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * Entry point of the DataValues Interfaces library.
+ *
+ * @since 0.1
+ * @codeCoverageIgnore
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+
+if ( defined( 'DATAVALUES_INTERFACES_VERSION' ) ) {
+ // Do not initialize more than once.
+ return 1;
+}
+
+define( 'DATAVALUES_INTERFACES_VERSION', '0.2.5' );
diff --git a/www/wiki/vendor/data-values/interfaces/README.md b/www/wiki/vendor/data-values/interfaces/README.md
new file mode 100644
index 00000000..96d5789e
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/README.md
@@ -0,0 +1,119 @@
+# DataValues Interfaces
+
+DataValues Interfaces is a small PHP library that defines a set of interfaces for parsers,
+formatters and validators.
+
+It is part of the [DataValues set of libraries](https://github.com/DataValues).
+
+[![Build Status](https://secure.travis-ci.org/DataValues/Interfaces.png?branch=master)](http://travis-ci.org/DataValues/Interfaces)
+[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Interfaces/badges/coverage.png?s=6432d29bf3fed068995e66093ad52e053099a916)](https://scrutinizer-ci.com/g/DataValues/Interfaces/)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Interfaces/badges/quality-score.png?s=da1bb6ea09762d9e3a143e473cdefa712db46804)](https://scrutinizer-ci.com/g/DataValues/Interfaces/)
+
+On [Packagist](https://packagist.org/packages/data-values/interfaces):
+[![Latest Stable Version](https://poser.pugx.org/data-values/interfaces/version.png)](https://packagist.org/packages/data-values/interfaces)
+[![Download count](https://poser.pugx.org/data-values/interfaces/d/total.png)](https://packagist.org/packages/data-values/interfaces)
+
+## Requirements
+
+* PHP 5.5 or later
+
+## Installation
+
+You can use [Composer](http://getcomposer.org/) to download and install
+this package as well as its dependencies. Alternatively you can simply clone
+the git repository and take care of loading yourself.
+
+### Composer
+
+To add this package as a local, per-project dependency to your project, simply add a
+dependency on `data-values/interfaces` to your project's `composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a dependency on
+DataValues Interfaces 0.2:
+
+ {
+ "require": {
+ "data-values/interfaces": "0.2.*"
+ }
+ }
+
+### Manual
+
+Get the DataValues Interfaces code, either via git, or some other means. Also get all dependencies.
+You can find a list of the dependencies in the "require" section of the composer.json file.
+Load all dependencies and the load the DataValues Interfaces library by including its entry point:
+Interfaces.php.
+
+## Tests
+
+This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these
+tests using the PHPUnit configuration file found in the root directory. The tests can also be run
+via TravisCI, as a TravisCI configuration file is also provided in the root directory.
+
+## Authors
+
+DataValues Interfaces has been written by [Jeroen De Dauw](https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw),
+as [Wikimedia Germany](https://wikimedia.de) employee for the [Wikidata project](https://wikidata.org/).
+
+## Release notes
+
+### 0.2.5 (2017-08-09)
+
+* Removed MediaWiki extension credits registration
+
+### 0.2.4 (2017-08-02)
+
+* Fixed `ValueFormatterTestBase` not being installable via Composer.
+
+### 0.2.3 (2017-08-02)
+
+* Updated minimal required PHP version from 5.3 to 5.5.9.
+* Minor fixes to code documentation.
+* Added PHPCS support.
+
+### 0.2.2 (2016-07-15)
+
+* Fixed `ValueFormatterTestBase` not doing strict string comparisons.
+
+### 0.2.1 (2016-01-13)
+
+* Fixed an issue when using this component with HHVM 1.11.0 (see #21).
+
+### 0.2.0 (2015-08-11)
+
+* Dropped deprecated `ErrorObject`, use `Error` instead
+* Dropped deprecated `ResultObject`, use `Result` instead
+* Dropped deprecated constant `DataValuesInterfaces_VERSION`, use `DATAVALUES_INTERFACES_VERSION` instead
+* Dropped `ValueFormatterTestBase::getFormatterClass`
+* Made `ValueFormatterTestBase::getInstance` abstract
+* The options in `ValueFormatterTestBase::getInstance` are now optional
+
+### 0.1.5 (2015-02-14)
+
+* The options in the `ValueFormatterBase` constructor are now optional
+* The MediaWiki extension registration now includes the license
+
+### 0.1.4 (2014-04-14)
+
+* Added rawValue and expectedFormat arguments to `ValueParsers\ParseException`
+
+### 0.1.3 (2014-03-31)
+
+* Added `ValueFormatters\FormattingException`
+
+### 0.1.2 (2013-11-22)
+
+* Improved autoloading code
+* Fixed link in MediaWiki credits
+* Renamed entry point from DataValuesInterfaces.php to Interfaces.php
+
+### 0.1.0 (2013-11-16)
+
+Initial release with these features:
+
+* `ValueFormatters\ValueFormatter` interface
+* `ValueParsers\ValueParser` interface
+* `ValueValidators\ValueValidator` interface
+
+## Links
+
+* [DataValues Interfaces on Packagist](https://packagist.org/packages/data-values/interfaces)
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php
new file mode 100644
index 00000000..133f01e1
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormatterOptions.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace ValueFormatters;
+
+use InvalidArgumentException;
+use OutOfBoundsException;
+use RuntimeException;
+
+/**
+ * Object holding options for a formatter.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+final class FormatterOptions {
+
+ /**
+ * @since 0.1
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * @since 0.1
+ *
+ * @param array $options
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct( array $options = [] ) {
+ foreach ( array_keys( $options ) as $option ) {
+ if ( !is_string( $option ) ) {
+ throw new InvalidArgumentException( 'Option names need to be strings' );
+ }
+ }
+
+ $this->options = $options;
+ }
+
+ /**
+ * Sets the value of the specified option.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $value
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setOption( $option, $value ) {
+ if ( !is_string( $option ) ) {
+ throw new InvalidArgumentException( 'Option name needs to be a string' );
+ }
+
+ $this->options[$option] = $value;
+ }
+
+ /**
+ * Returns the value of the specified option. If the option is not set,
+ * an InvalidArgumentException is thrown.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws OutOfBoundsException
+ * @return mixed
+ */
+ public function getOption( $option ) {
+ if ( !array_key_exists( $option, $this->options ) ) {
+ throw new OutOfBoundsException( "Option '$option' has not been set so cannot be obtained" );
+ }
+
+ return $this->options[$option];
+ }
+
+ /**
+ * Returns if the specified option is set or not.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @return bool
+ */
+ public function hasOption( $option ) {
+ return array_key_exists( $option, $this->options );
+ }
+
+ /**
+ * Sets the value of an option to the provided default in case the option is not set yet.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $default
+ */
+ public function defaultOption( $option, $default ) {
+ if ( !$this->hasOption( $option ) ) {
+ $this->setOption( $option, $default );
+ }
+ }
+
+ /**
+ * Requires an option to be set.
+ * If it's not set, a RuntimeException is thrown.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws RuntimeException
+ */
+ public function requireOption( $option ) {
+ if ( !$this->hasOption( $option ) ) {
+ throw new RuntimeException( 'Required option"' . $option . '" is not set' );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php
new file mode 100644
index 00000000..afda7227
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/FormattingException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace ValueFormatters;
+
+use RuntimeException;
+
+/**
+ * @since 0.1.3
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class FormattingException extends RuntimeException {
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php
new file mode 100644
index 00000000..909b3145
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatter.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace ValueFormatters;
+
+/**
+ * Interface for value formatters, typically (but not limited to) expecting a DataValue object and
+ * returning a string.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface ValueFormatter {
+
+ /**
+ * Identifier for the option that holds the code of the language in which the formatter should
+ * operate.
+ * @since 0.1
+ */
+ const OPT_LANG = 'lang';
+
+ /**
+ * @since 0.1
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ * @throws FormattingException
+ */
+ public function format( $value );
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php
new file mode 100644
index 00000000..3fd7ca2e
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueFormatters/ValueFormatterBase.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace ValueFormatters;
+
+/**
+ * Base class for ValueFormatters.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class ValueFormatterBase implements ValueFormatter {
+
+ /**
+ * @since 0.1
+ *
+ * @var FormatterOptions
+ */
+ protected $options;
+
+ /**
+ * @since 0.1
+ *
+ * @param FormatterOptions|null $options
+ */
+ public function __construct( FormatterOptions $options = null ) {
+ $this->options = $options ?: new FormatterOptions();
+
+ $this->options->defaultOption( ValueFormatter::OPT_LANG, 'en' );
+ }
+
+ /**
+ * Shortcut to $this->options->getOption.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @return mixed
+ */
+ final protected function getOption( $option ) {
+ return $this->options->getOption( $option );
+ }
+
+ /**
+ * Shortcut to $this->options->requireOption.
+ *
+ * @param string $option
+ */
+ final protected function requireOption( $option ) {
+ $this->options->requireOption( $option );
+ }
+
+ /**
+ * Shortcut to $this->options->defaultOption.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $default
+ */
+ final protected function defaultOption( $option, $default ) {
+ $this->options->defaultOption( $option, $default );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php
new file mode 100644
index 00000000..151d9a57
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParseException.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace ValueParsers;
+
+use RuntimeException;
+
+/**
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class ParseException extends RuntimeException {
+
+ /**
+ * @var string|null
+ */
+ private $expectedFormat;
+
+ /**
+ * @var string|null
+ */
+ private $rawValue;
+
+ /**
+ * @param string $message A plain english message describing the error
+ * @param string|null $rawValue The raw value that failed to be parsed.
+ * @param string|null $expectedFormat An identifier for the format the raw value
+ * did not match
+ *
+ * @since 0.1.4
+ */
+ public function __construct( $message, $rawValue = null, $expectedFormat = null ) {
+ parent::__construct( $message );
+ $this->expectedFormat = $expectedFormat;
+ $this->rawValue = $rawValue;
+ }
+
+ /**
+ * An identifier for the format the raw value did not match.
+ *
+ * This does not necessarily specify the exact format the throwing parser accepts.
+ * For example, a PositiveFloatParser might throw a ParseException with the
+ * expected format 'float' if the value does not even parse as a float, while
+ * in fact the parser would only accept positive floats. However, if the user
+ * enters a negative float, the parser must throw with a more specific format,
+ * i. e. 'positive-float'.
+ *
+ * @since 0.1.4
+ */
+ public function getExpectedFormat() {
+ return $this->expectedFormat;
+ }
+
+ /**
+ * The raw value which was not parsable.
+ *
+ * This is not necessarily the value an user entered, but the rawest value
+ * that's available at the throwing site.
+ *
+ * @since 0.1.4
+ */
+ public function getRawValue() {
+ return $this->rawValue;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php
new file mode 100644
index 00000000..d06413f1
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ParserOptions.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace ValueParsers;
+
+use InvalidArgumentException;
+use RuntimeException;
+
+/**
+ * Object holding options for a parser.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+final class ParserOptions {
+
+ /**
+ * @since 0.1
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * @since 0.1
+ *
+ * @param array $options
+ *
+ * @throws InvalidArgumentException
+ */
+ public function __construct( array $options = [] ) {
+ foreach ( array_keys( $options ) as $option ) {
+ if ( !is_string( $option ) ) {
+ throw new InvalidArgumentException( 'Option names need to be strings.' );
+ }
+ }
+
+ $this->options = $options;
+ }
+
+ /**
+ * Sets the value of the specified option.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $value
+ *
+ * @throws InvalidArgumentException
+ */
+ public function setOption( $option, $value ) {
+ if ( !is_string( $option ) ) {
+ throw new InvalidArgumentException( 'Option name needs to be a string.' );
+ }
+
+ $this->options[$option] = $value;
+ }
+
+ /**
+ * Returns the value of the specified option. If the option is not set,
+ * an InvalidArgumentException is thrown.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws InvalidArgumentException
+ * @return mixed
+ */
+ public function getOption( $option ) {
+ if ( !array_key_exists( $option, $this->options ) ) {
+ throw new InvalidArgumentException();
+ }
+
+ return $this->options[$option];
+ }
+
+ /**
+ * Returns if the specified option is set or not.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @return bool
+ */
+ public function hasOption( $option ) {
+ return array_key_exists( $option, $this->options );
+ }
+
+ /**
+ * Sets the value of an option to the provided default in case the option is not set yet.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ * @param mixed $default
+ */
+ public function defaultOption( $option, $default ) {
+ if ( !$this->hasOption( $option ) ) {
+ $this->setOption( $option, $default );
+ }
+ }
+
+ /**
+ * Requires an option to be set.
+ * If it's not set, a RuntimeException is thrown.
+ *
+ * @since 0.1
+ *
+ * @param string $option
+ *
+ * @throws RuntimeException
+ */
+ public function requireOption( $option ) {
+ if ( !$this->hasOption( $option ) ) {
+ throw new RuntimeException( 'Required option "' . $option . '" is not set.' );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php
new file mode 100644
index 00000000..c2027461
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueParsers/ValueParser.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace ValueParsers;
+
+/**
+ * Interface for value parsers, typically (but not limited to) expecting a string and returning a
+ * DataValue object.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface ValueParser {
+
+ /**
+ * Identifier for the option that holds the code of the language in which the parser should
+ * operate.
+ * @since 0.1
+ */
+ const OPT_LANG = 'lang';
+
+ /**
+ * @since 0.1
+ *
+ * @param mixed $value
+ *
+ * @return mixed
+ */
+ public function parse( $value );
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php
new file mode 100644
index 00000000..a368e5e0
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Error.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace ValueValidators;
+
+/**
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class Error {
+
+ const SEVERITY_ERROR = 9;
+ const SEVERITY_WARNING = 4;
+
+ protected $text;
+ protected $severity;
+ protected $property;
+
+ protected $code;
+ protected $params;
+
+ /**
+ * @since 0.1
+ *
+ * @param string $text
+ * @param string|null $property
+ * @param string $code
+ * @param array $params
+ *
+ * @return self
+ */
+ public static function newError( $text = '', $property = null, $code = 'invalid', array $params = [] ) {
+ return new static( $text, self::SEVERITY_ERROR, $property, $code, $params );
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param string $text
+ * @param integer $severity
+ * @param string|null $property
+ * @param string $code
+ * @param array $params
+ */
+ protected function __construct( $text, $severity, $property, $code, array $params ) {
+ $this->text = $text;
+ $this->severity = $severity;
+ $this->property = $property;
+ $this->code = $code;
+ $this->params = $params;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @return integer, element of the ValueValidatorError::SEVERITY_ enum
+ */
+ public function getSeverity() {
+ return $this->severity;
+ }
+
+ /**
+ * Returns the property of the value for which the error occurred, or null if it occurred for the value itself.
+ *
+ * @since 0.1
+ *
+ * @return string|null
+ */
+ public function getProperty() {
+ return $this->property;
+ }
+
+ /**
+ * @return array
+ */
+ public function getParameters() {
+ return $this->params;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCode() {
+ return $this->code;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php
new file mode 100644
index 00000000..3f7225b8
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/Result.php
@@ -0,0 +1,114 @@
+<?php
+
+namespace ValueValidators;
+
+/**
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class Result {
+
+ /**
+ * @since 0.1
+ *
+ * @var bool
+ */
+ protected $isValid;
+
+ /**
+ * @since 0.1
+ *
+ * @var Error[]
+ */
+ protected $errors = [];
+
+ /**
+ * @since 0.1
+ *
+ * @return self
+ */
+ public static function newSuccess() {
+ return new static( true );
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param Error[] $errors
+ *
+ * @return self
+ */
+ public static function newError( array $errors ) {
+ return new static( false, $errors );
+ }
+
+ /**
+ * Returns a result that represents the combination of the two given results.
+ * In particular, this means:
+ *
+ * If $a->getErrors() is empty and $a->isValid() is true, $b is returned.
+ * If $b->getErrors() is empty and $b->isValid() is true, $a is returned.
+ *
+ * Otherwise, a new Result is constructed that contains
+ * all errors from $a and $b, and is considered valid
+ * if both $a and $b were valid.
+ *
+ * @since 0.1
+ *
+ * @param self $a
+ * @param self $b
+ *
+ * @return self
+ */
+ public static function merge( self $a, self $b ) {
+ $aErrors = $a->getErrors();
+ $bErrors = $b->getErrors();
+
+ if ( $a->isValid() && empty( $aErrors ) ) {
+ return $b;
+ } elseif ( $b->isValid() && empty( $bErrors ) ) {
+ return $a;
+ } else {
+ $errors = array_merge( $aErrors, $bErrors );
+ $valid = ( $a->isValid() && $b->isValid() );
+
+ return new self( $valid, $errors );
+ }
+ }
+
+ /**
+ * @since 0.1
+ *
+ * @param bool $isValid
+ * @param Error[] $errors
+ */
+ protected function __construct( $isValid, array $errors = [] ) {
+ $this->isValid = $isValid;
+ $this->errors = $errors;
+ }
+
+ /**
+ * Returns if the value was found to be valid or not.
+ *
+ * @since 0.1
+ *
+ * @return bool
+ */
+ public function isValid() {
+ return $this->isValid;
+ }
+
+ /**
+ * Returns an array with the errors that occurred during validation.
+ *
+ * @since 0.1
+ *
+ * @return Error[]
+ */
+ public function getErrors() {
+ return $this->errors;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php
new file mode 100644
index 00000000..ce0d1aaa
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidator.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace ValueValidators;
+
+/**
+ * Interface for value validators.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface ValueValidator {
+
+ /**
+ * Parses a value.
+ *
+ * @since 0.1
+ *
+ * @param mixed $value The value to validate
+ *
+ * @return Result
+ */
+ public function validate( $value );
+
+ /**
+ * Takes an associative array with options and sets those known to the ValueValidator.
+ *
+ * @since 0.1
+ *
+ * @param array $options
+ */
+ public function setOptions( array $options );
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php
new file mode 100644
index 00000000..e38bd5c6
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/src/ValueValidators/ValueValidatorObject.php
@@ -0,0 +1,215 @@
+<?php
+
+namespace ValueValidators;
+
+/**
+ * ValueValidator that holds base validation functions for any type of object.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class ValueValidatorObject implements ValueValidator {
+
+ /**
+ * A list of allowed values. This means the parameters value(s) must be in the list
+ * during validation. False for no restriction.
+ *
+ * @since 0.1
+ *
+ * @var array|false
+ */
+ protected $allowedValues = false;
+
+ /**
+ * A list of prohibited values. This means the parameters value(s) must
+ * not be in the list during validation. False for no restriction.
+ *
+ * @since 0.1
+ *
+ * @var array|false
+ */
+ protected $prohibitedValues = false;
+
+ /**
+ * @since 0.1
+ *
+ * @var array
+ */
+ protected $options = [];
+
+ /**
+ * @since 0.1
+ *
+ * @var Error[]
+ */
+ protected $errors = [];
+
+ /**
+ * @see ValueValidator::validate
+ *
+ * @param mixed $value
+ *
+ * @return Result
+ */
+ final public function validate( $value ) {
+ $this->errors = [];
+
+ if ( $this->enableWhitelistRestrictions() ) {
+ $this->valueIsAllowed( $value );
+ }
+
+ $this->doValidation( $value );
+
+ if ( $this->errors === [] ) {
+ return Result::newSuccess();
+ } else {
+ return Result::newError( $this->errors );
+ }
+ }
+
+ /**
+ * Checks the value against the allowed values and prohibited values lists in case they are set.
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ */
+ protected function valueIsAllowed( $value ) {
+ if ( $this->allowedValues !== false && !in_array( $value, $this->allowedValues, true ) ) {
+ $this->addErrorMessage( 'Value not in whitelist' );
+ }
+
+ if ( $this->prohibitedValues !== false && in_array( $value, $this->prohibitedValues, true ) ) {
+ $this->addErrorMessage( 'Value in blacklist' );
+ }
+ }
+
+ /**
+ * @see ValueValidator::validate
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ */
+ abstract public function doValidation( $value );
+
+ /**
+ * Sets the parameter definition values contained in the provided array.
+ * @see ParamDefinition::setArrayValues
+ *
+ * @param array $param
+ */
+ public function setOptions( array $param ) {
+ if ( $this->enableWhitelistRestrictions() ) {
+ if ( array_key_exists( 'values', $param ) ) {
+ $this->allowedValues = $param['values'];
+ }
+
+ if ( array_key_exists( 'excluding', $param ) ) {
+ $this->prohibitedValues = $param['excluding'];
+ }
+ }
+
+ $this->options = $param;
+ }
+
+ /**
+ * Registers an error message.
+ *
+ * @since 0.1
+ *
+ * @param string $errorMessage
+ */
+ protected function addErrorMessage( $errorMessage ) {
+ $this->addError( Error::newError( $errorMessage ) );
+ }
+
+ /**
+ * Registers an error.
+ *
+ * @since 0.1
+ *
+ * @param Error $error
+ */
+ protected function addError( Error $error ) {
+ $this->errors[] = $error;
+ }
+
+ /**
+ * Registers a list of errors.
+ *
+ * @since 0.1
+ *
+ * @param Error[] $errors
+ */
+ protected function addErrors( array $errors ) {
+ $this->errors = array_merge( $this->errors, $errors );
+ }
+
+ /**
+ * Runs the value through the provided ValueValidator and registers the errors.
+ * Options of $this can be mapped to those of the passed ValueValidator using
+ * the $optionMap parameter in which keys are source names and values are target
+ * names.
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ * @param ValueValidator $validator
+ * @param string|null $property
+ * @param array $optionMap
+ */
+ protected function runSubValidator(
+ $value,
+ ValueValidator $validator,
+ $property = null,
+ array $optionMap = []
+ ) {
+ if ( $optionMap !== [] ) {
+ $options = [];
+
+ foreach ( $optionMap as $source => $target ) {
+ if ( array_key_exists( $source, $this->options ) ) {
+ $options[$target] = $this->options[$source];
+ }
+ }
+
+ $validator->setOptions( $options );
+ }
+
+ /**
+ * @var Error $error
+ */
+ foreach ( $validator->validate( $value )->getErrors() as $error ) {
+ $this->addError( Error::newError( $error->getText(), $property ) );
+ }
+ }
+
+ /**
+ * If the "values" and "excluding" arguments should be held into account.
+ *
+ * @since 0.1
+ *
+ * @return bool
+ */
+ protected function enableWhitelistRestrictions() {
+ return true;
+ }
+
+ /**
+ * Returns the allowed values.
+ *
+ * TODO: think about how to access set options in general and if we want to have
+ * whitelist and baclklist values in the validator objects to begin with.
+ *
+ * @since 0.1
+ *
+ * @return array|bool false
+ */
+ public function getWhitelistedValues() {
+ return $this->allowedValues;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php
new file mode 100644
index 00000000..f611149d
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/FormatterOptionsTest.php
@@ -0,0 +1,191 @@
+<?php
+
+namespace ValueFormatters\Test;
+
+use ValueFormatters\FormatterOptions;
+
+/**
+ * @covers ValueFormatters\FormatterOptions
+ *
+ * @group ValueFormatters
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class FormatterOptionsTest extends \PHPUnit_Framework_TestCase {
+
+ public function testConstructor() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $formatterOptions = new FormatterOptions( $options );
+
+ foreach ( $options as $option => $value ) {
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $formatterOptions->getOption( $option ) ),
+ 'Option should be set properly'
+ );
+ }
+
+ $this->assertFalse( $formatterOptions->hasOption( 'ohi' ) );
+ }
+
+ public function testConstructorFail() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 42 => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $this->setExpectedException( 'Exception' );
+
+ new FormatterOptions( $options );
+ }
+
+ public function setOptionProvider() {
+ $argLists = [];
+
+ $formatterOptions = new FormatterOptions();
+
+ $argLists[] = [ $formatterOptions, 'foo', 42 ];
+ $argLists[] = [ $formatterOptions, 'bar', 42 ];
+ $argLists[] = [ $formatterOptions, 'foo', 'foo' ];
+ $argLists[] = [ $formatterOptions, 'foo', null ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider setOptionProvider
+ */
+ public function testSetAndGetOption( FormatterOptions $options, $option, $value ) {
+ $options->setOption( $option, $value );
+
+ $this->assertEquals(
+ $value,
+ $options->getOption( $option ),
+ 'Setting an option should work'
+ );
+ }
+
+ public function testHashOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $formatterOptions = new FormatterOptions( $options );
+
+ foreach ( array_keys( $options ) as $option ) {
+ $this->assertTrue( $formatterOptions->hasOption( $option ) );
+ }
+
+ $this->assertFalse( $formatterOptions->hasOption( 'ohi' ) );
+ $this->assertFalse( $formatterOptions->hasOption( 'Foo' ) );
+ }
+
+ public function testSetOption() {
+ $formatterOptions = new FormatterOptions( [ 'foo' => 'bar' ] );
+
+ $values = [
+ [ 'foo', 'baz' ],
+ [ 'foo', 'bar' ],
+ [ 'onoez', '' ],
+ [ 'hax', 'zor' ],
+ [ 'nyan', 9001 ],
+ [ 'cat', 4.2 ],
+ [ 'spam', [ '~=[,,_,,]:3' ] ],
+ ];
+
+ foreach ( $values as $value ) {
+ $formatterOptions->setOption( $value[0], $value[1] );
+ $this->assertSame( $value[1], $formatterOptions->getOption( $value[0] ) );
+ }
+ }
+
+ /**
+ * @dataProvider nonExistingOptionsProvider
+ */
+ public function testGetOption( $nonExistingOption ) {
+ $this->assertTrue( true );
+ $formatterOptions = new FormatterOptions( [ 'foo' => 'bar' ] );
+
+ $this->setExpectedException( 'OutOfBoundsException' );
+
+ $formatterOptions->getOption( $nonExistingOption );
+ }
+
+ public function nonExistingOptionsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 'bar' ];
+ $argLists[] = [ 'Foo' ];
+ $argLists[] = [ 'FOO' ];
+ $argLists[] = [ 'spam' ];
+ $argLists[] = [ 'onoez' ];
+
+ return $argLists;
+ }
+
+ public function testRequireOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $formatterOptions = new FormatterOptions( $options );
+
+ foreach ( array_keys( $options ) as $option ) {
+ $formatterOptions->requireOption( $option );
+ }
+
+ $this->setExpectedException( 'Exception' );
+
+ $formatterOptions->requireOption( 'Foo' );
+ }
+
+ public function testDefaultOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $formatterOptions = new FormatterOptions( $options );
+
+ foreach ( $options as $option => $value ) {
+ $formatterOptions->defaultOption( $option, 9001 );
+
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $formatterOptions->getOption( $option ) ),
+ 'Defaulting a set option should not affect its value'
+ );
+ }
+
+ $defaults = [
+ 'N' => 42,
+ 'y' => 4.2,
+ 'a' => false,
+ 'n' => [ '42' => 42, [ '' ] ]
+ ];
+
+ foreach ( $defaults as $option => $value ) {
+ $formatterOptions->defaultOption( $option, $value );
+
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $formatterOptions->getOption( $option ) ),
+ 'Defaulting a not set option should affect its value'
+ );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php
new file mode 100644
index 00000000..6252b7b2
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/ValueFormatters/ValueFormatterTestBase.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace ValueFormatters\Test;
+
+use ValueFormatters\FormatterOptions;
+use ValueFormatters\ValueFormatter;
+
+/**
+ * Base for unit tests for ValueFormatter implementing classes.
+ *
+ * @since 0.1
+ *
+ * @group ValueFormatters
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+abstract class ValueFormatterTestBase extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * Returns a list with valid inputs and their associated formatting output.
+ *
+ * @since 0.1
+ *
+ * @return array[]
+ */
+ abstract public function validProvider();
+
+ /**
+ * @since 0.1
+ *
+ * @param FormatterOptions|null $options
+ *
+ * @return ValueFormatter
+ */
+ abstract protected function getInstance( FormatterOptions $options = null );
+
+ /**
+ * @dataProvider validProvider
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ * @param mixed $expected
+ * @param FormatterOptions|null $options
+ * @param ValueFormatter|null $formatter
+ */
+ public function testValidFormat(
+ $value,
+ $expected,
+ FormatterOptions $options = null,
+ ValueFormatter $formatter = null
+ ) {
+ if ( $formatter === null ) {
+ $formatter = $this->getInstance( $options );
+ }
+
+ $this->assertSame( $expected, $formatter->format( $value ) );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php
new file mode 100644
index 00000000..8a97ecb7
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/ValueParsers/ParserOptionsTest.php
@@ -0,0 +1,191 @@
+<?php
+
+namespace ValueParsers\Test;
+
+use ValueParsers\ParserOptions;
+
+/**
+ * @covers ValueParsers\ParserOptions
+ *
+ * @group ValueParsers
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class ParserOptionsTest extends \PHPUnit_Framework_TestCase {
+
+ public function testConstructor() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $parserOptions = new ParserOptions( $options );
+
+ foreach ( $options as $option => $value ) {
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $parserOptions->getOption( $option ) ),
+ 'Option should be set properly'
+ );
+ }
+
+ $this->assertFalse( $parserOptions->hasOption( 'ohi' ) );
+ }
+
+ public function testConstructorFail() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 42 => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $this->setExpectedException( 'Exception' );
+
+ new ParserOptions( $options );
+ }
+
+ public function setOptionProvider() {
+ $argLists = [];
+
+ $parserOptions = new ParserOptions();
+
+ $argLists[] = [ $parserOptions, 'foo', 42 ];
+ $argLists[] = [ $parserOptions, 'bar', 42 ];
+ $argLists[] = [ $parserOptions, 'foo', 'foo' ];
+ $argLists[] = [ $parserOptions, 'foo', null ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider setOptionProvider
+ */
+ public function testSetAndGetOption( ParserOptions $options, $option, $value ) {
+ $options->setOption( $option, $value );
+
+ $this->assertEquals(
+ $value,
+ $options->getOption( $option ),
+ 'Setting an option should work'
+ );
+ }
+
+ public function testHashOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $parserOptions = new ParserOptions( $options );
+
+ foreach ( array_keys( $options ) as $option ) {
+ $this->assertTrue( $parserOptions->hasOption( $option ) );
+ }
+
+ $this->assertFalse( $parserOptions->hasOption( 'ohi' ) );
+ $this->assertFalse( $parserOptions->hasOption( 'Foo' ) );
+ }
+
+ public function testSetOption() {
+ $parserOptions = new ParserOptions( [ 'foo' => 'bar' ] );
+
+ $values = [
+ [ 'foo', 'baz' ],
+ [ 'foo', 'bar' ],
+ [ 'onoez', '' ],
+ [ 'hax', 'zor' ],
+ [ 'nyan', 9001 ],
+ [ 'cat', 4.2 ],
+ [ 'spam', [ '~=[,,_,,]:3' ] ],
+ ];
+
+ foreach ( $values as $value ) {
+ $parserOptions->setOption( $value[0], $value[1] );
+ $this->assertSame( $value[1], $parserOptions->getOption( $value[0] ) );
+ }
+ }
+
+ /**
+ * @dataProvider nonExistingOptionsProvider
+ */
+ public function testGetOption( $nonExistingOption ) {
+ $this->assertTrue( true );
+ $formatterOptions = new ParserOptions( [ 'foo' => 'bar' ] );
+
+ $this->setExpectedException( 'InvalidArgumentException' );
+
+ $formatterOptions->getOption( $nonExistingOption );
+ }
+
+ public function nonExistingOptionsProvider() {
+ $argLists = [];
+
+ $argLists[] = [ 'bar' ];
+ $argLists[] = [ 'Foo' ];
+ $argLists[] = [ 'FOO' ];
+ $argLists[] = [ 'spam' ];
+ $argLists[] = [ 'onoez' ];
+
+ return $argLists;
+ }
+
+ public function testRequireOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $parserOptions = new ParserOptions( $options );
+
+ foreach ( array_keys( $options ) as $option ) {
+ $parserOptions->requireOption( $option );
+ }
+
+ $this->setExpectedException( 'Exception' );
+
+ $parserOptions->requireOption( 'Foo' );
+ }
+
+ public function testDefaultOption() {
+ $options = [
+ 'foo' => 42,
+ 'bar' => 4.2,
+ 'baz' => [ 'o_O', false, null, '42' => 42, [] ]
+ ];
+
+ $parserOptions = new ParserOptions( $options );
+
+ foreach ( $options as $option => $value ) {
+ $parserOptions->defaultOption( $option, 9001 );
+
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $parserOptions->getOption( $option ) ),
+ 'Defaulting a set option should not affect its value'
+ );
+ }
+
+ $defaults = [
+ 'N' => 42,
+ 'y' => 4.2,
+ 'a' => false,
+ 'n' => [ '42' => 42, [ '' ] ]
+ ];
+
+ foreach ( $defaults as $option => $value ) {
+ $parserOptions->defaultOption( $option, $value );
+
+ $this->assertSame(
+ serialize( $value ),
+ serialize( $parserOptions->getOption( $option ) ),
+ 'Defaulting a not set option should affect its value'
+ );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php
new file mode 100644
index 00000000..d5ba9fbd
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ErrorTest.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace ValueValidators\Test;
+
+use ValueValidators\Error;
+
+/**
+ * @covers ValueValidators\Error
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class ErrorTest extends \PHPUnit_Framework_TestCase {
+
+ public function newErrorProvider() {
+ $argLists = [];
+
+ $argLists[] = [];
+
+ $argLists[] = [ '' ];
+ $argLists[] = [ 'foo' ];
+ $argLists[] = [ ' foo bar baz.' ];
+
+ $argLists[] = [ ' foo bar ', null ];
+ $argLists[] = [ ' foo bar ', 'length' ];
+
+ $argLists[] = [ ' foo bar ', null, 'something-went-wrong' ];
+ $argLists[] = [ ' foo bar ', null, 'something-went-wrong', [ 'foo', 'bar' ] ];
+
+ return $argLists;
+ }
+
+ /**
+ * @dataProvider newErrorProvider
+ */
+ public function testNewError() {
+ $args = func_get_args();
+
+ $error = call_user_func_array( [ Error::class, 'newError' ], $args );
+
+ /**
+ * @var Error $error
+ */
+ $this->assertInstanceOf( 'ValueValidators\Error', $error );
+
+ $this->assertInternalType( 'string', $error->getText() );
+ $this->assertInternalType( 'integer', $error->getSeverity() );
+ $this->assertTrue( is_string( $error->getProperty() ) || is_null( $error->getProperty() ) );
+ $this->assertInternalType( 'string', $error->getCode() );
+ $this->assertInternalType( 'array', $error->getParameters() );
+
+ if ( count( $args ) > 0 ) {
+ $this->assertSame( $args[0], $error->getText() );
+ }
+
+ if ( count( $args ) > 1 ) {
+ $this->assertSame( $args[1], $error->getProperty() );
+ }
+
+ if ( count( $args ) > 2 ) {
+ $this->assertSame( $args[2], $error->getCode() );
+ }
+
+ if ( count( $args ) > 3 ) {
+ $this->assertSame( $args[3], $error->getParameters() );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php
new file mode 100644
index 00000000..69e5a72d
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/ValueValidators/ResultTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace ValueValidators\Test;
+
+use ValueValidators\Error;
+use ValueValidators\Result;
+
+/**
+ * @covers ValueValidators\Result
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ */
+class ResultTest extends \PHPUnit_Framework_TestCase {
+
+ public function testNewSuccess() {
+ $result = Result::newSuccess();
+
+ $this->assertTrue( $result->isValid() );
+ $this->assertEmpty( $result->getErrors() );
+ }
+
+ public function testNewError() {
+ $result = Result::newError( [
+ Error::newError( 'foo' ),
+ Error::newError( 'bar' ),
+ ] );
+
+ $this->assertFalse( $result->isValid() );
+ $this->assertCount( 2, $result->getErrors() );
+ }
+
+ public static function provideMerge() {
+ $errors = [
+ Error::newError( 'foo' ),
+ Error::newError( 'bar' ),
+ ];
+
+ return [
+ [
+ Result::newSuccess(),
+ Result::newSuccess(),
+ true,
+ 0,
+ 'success + success'
+ ],
+ [
+ Result::newSuccess(),
+ Result::newError( $errors ),
+ false,
+ 2,
+ 'success + error'
+ ],
+ [
+ Result::newSuccess(),
+ Result::newError( $errors ),
+ false,
+ 2,
+ 'error + success'
+ ],
+ [
+ Result::newError( $errors ),
+ Result::newError( $errors ),
+ false,
+ 4,
+ 'error + error'
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider provideMerge
+ */
+ public function testMerge( $a, $b, $expectedValid, $expectedErrorCount, $message ) {
+ $result = Result::merge( $a, $b );
+
+ $this->assertSame( $expectedValid, $result->isValid(), $message );
+ $this->assertCount( $expectedErrorCount, $result->getErrors(), $message );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php b/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php
new file mode 100644
index 00000000..ac82d460
--- /dev/null
+++ b/www/wiki/vendor/data-values/interfaces/tests/bootstrap.php
@@ -0,0 +1,14 @@
+<?php
+
+if ( PHP_SAPI !== 'cli' ) {
+ die( 'Not an entry point' );
+}
+
+error_reporting( E_ALL | E_STRICT );
+ini_set( 'display_errors', 1 );
+
+if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
+ die( 'You need to install this package with Composer before you can run the tests' );
+}
+
+require_once __DIR__ . '/../vendor/autoload.php';
diff --git a/www/wiki/vendor/data-values/validators/.gitignore b/www/wiki/vendor/data-values/validators/.gitignore
new file mode 100644
index 00000000..577795cb
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/.gitignore
@@ -0,0 +1,12 @@
+*~
+*.kate-swp
+*.swp
+
+!.*
+
+.idea/
+build/
+vendor/
+
+composer.phar
+composer.lock \ No newline at end of file
diff --git a/www/wiki/vendor/data-values/validators/.phpcs.xml b/www/wiki/vendor/data-values/validators/.phpcs.xml
new file mode 100644
index 00000000..1ee8fc09
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/.phpcs.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<ruleset>
+ <rule ref="./vendor/wikibase/wikibase-codesniffer/Wikibase">
+ <exclude name="Generic.Arrays.DisallowLongArraySyntax" />
+ </rule>
+
+ <rule ref="Generic.Files.LineLength">
+ <properties>
+ <property name="lineLimit" value="106" />
+ </properties>
+ </rule>
+
+ <file>.</file>
+</ruleset>
diff --git a/www/wiki/vendor/data-values/validators/.scrutinizer.yml b/www/wiki/vendor/data-values/validators/.scrutinizer.yml
new file mode 100644
index 00000000..d3e813a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/.scrutinizer.yml
@@ -0,0 +1,18 @@
+build: true
+inherit: true
+
+tools:
+ external_code_coverage: true
+ php_code_coverage: true
+ php_code_sniffer: true
+ php_cpd: true
+ php_cs_fixer: true
+ php_loc: true
+ php_mess_detector: true
+ php_pdepend: true
+ php_analyzer: true
+ sensiolabs_security_checker: true
+
+filter:
+ excluded_paths:
+ - 'vendor/*'
diff --git a/www/wiki/vendor/data-values/validators/.travis.yml b/www/wiki/vendor/data-values/validators/.travis.yml
new file mode 100644
index 00000000..8ca18641
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/.travis.yml
@@ -0,0 +1,27 @@
+language: php
+
+dist: trusty
+
+php:
+ - 5.5
+ - 5.6
+ - 7.0
+ - 7.1
+ - 7.2
+ - hhvm
+
+before_script:
+ - composer install --prefer-source
+
+script:
+ - composer test
+
+after_success:
+ - if [[ "`phpenv version-name`" != "7.1" ]]; then exit 0; fi
+ - phpunit --coverage-clover coverage.clover
+ - wget https://scrutinizer-ci.com/ocular.phar
+ - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
+
+cache:
+ directories:
+ - $HOME/.composer/cache
diff --git a/www/wiki/vendor/data-values/validators/COPYING b/www/wiki/vendor/data-values/validators/COPYING
new file mode 100644
index 00000000..ebba08a4
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/COPYING
@@ -0,0 +1,347 @@
+The license text below "----" applies to all files within this distribution, other
+than those that are in a directory which contains files named "LICENSE" or
+"COPYING", or a subdirectory thereof. For those files, the license text contained in
+said file overrides any license information contained in directories of smaller depth.
+Alternative licenses are typically used for software that is provided by external
+parties, and merely packaged with this software for convenience.
+----
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
diff --git a/www/wiki/vendor/data-values/validators/README.md b/www/wiki/vendor/data-values/validators/README.md
new file mode 100644
index 00000000..3efdedf4
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/README.md
@@ -0,0 +1,84 @@
+# DataValues Validators
+
+DataValues Validators is a small library that contains common ValueValidator implementations.
+
+It is part of the [DataValues set of libraries](https://github.com/DataValues).
+
+[![Build Status](https://secure.travis-ci.org/DataValues/Validators.png?branch=master)](http://travis-ci.org/DataValues/Validators)
+[![Code Coverage](https://scrutinizer-ci.com/g/DataValues/Validators/badges/coverage.png?s=677e53b2fab73a0bfad4aabe3f229f2f9d287a00)](https://scrutinizer-ci.com/g/DataValues/Validators/)
+[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/DataValues/Validators/badges/quality-score.png?s=6e5e7ac8557b7177926e89e39387e73f0bf87fe3)](https://scrutinizer-ci.com/g/DataValues/Validators/)
+
+On [Packagist](https://packagist.org/packages/data-values/validators):
+[![Latest Stable Version](https://poser.pugx.org/data-values/validators/version.png)](https://packagist.org/packages/data-values/validators)
+[![Download count](https://poser.pugx.org/data-values/validators/d/total.png)](https://packagist.org/packages/data-values/validators)
+
+## Installation
+
+The recommended way to use this library is via [Composer](http://getcomposer.org/).
+
+### Composer
+
+To add this package as a local, per-project dependency to your project, simply add a
+dependency on `data-values/validators` to your project's `composer.json` file.
+Here is a minimal example of a `composer.json` file that just defines a dependency on
+version 1.0 of this package:
+
+ {
+ "require": {
+ "data-values/validators": "1.0.*"
+ }
+ }
+
+### Manual
+
+Get the code of this package, either via git, or some other means. Also get all dependencies.
+You can find a list of the dependencies in the "require" section of the composer.json file.
+Then take care of autoloading the classes defined in the src directory.
+
+## Tests
+
+This library comes with a set up PHPUnit tests that cover all non-trivial code. You can run these
+tests using the PHPUnit configuration file found in the root directory. The tests can also be run
+via TravisCI, as a TravisCI configuration file is also provided in the root directory.
+
+## Authors
+
+DataValues Validators has been written by the Wikidata team, as [Wikimedia Germany](https://wikimedia.de)
+employees for the [Wikidata project](https://wikidata.org/).
+
+It is based upon and contains a lot of code written by [Jeroen De Dauw](https://github.com/JeroenDeDauw)
+for the [Maps](https://github.com/JeroenDeDauw/Maps) and
+[Semantic MediaWiki](https://semantic-mediawiki.org/) projects.
+
+## Release notes
+
+### 0.1.3 (2018-08-02)
+
+* Made component installable with DataValues 2.x
+* Removed MediaWiki integration
+
+### 0.1.2 (2014-10-09)
+
+* Made component installable with DataValues 1.x
+
+### 0.1.1 (2014-03-27)
+
+* Changed autoloading from PSR-0 to PSR-4
+* Added tests for DimensionValidator
+
+### 0.1.0 (2013-11-17)
+
+Initial release with these features:
+
+* DimensionValidator
+* ListValidator
+* NullValidator
+* RangeValidator
+* StringValidator
+* TitleValidator
+
+## Links
+
+* [DataValues Validators on Packagist](https://packagist.org/packages/data-values/validators)
+* [DataValues Validators on TravisCI](https://travis-ci.org/DataValues/Validators)
+* [DataValues Validators on ScrutinizerCI](https://scrutinizer-ci.com/g/DataValues/Validators/)
diff --git a/www/wiki/vendor/data-values/validators/composer.json b/www/wiki/vendor/data-values/validators/composer.json
new file mode 100644
index 00000000..0f9ddf2c
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/composer.json
@@ -0,0 +1,54 @@
+{
+ "name": "data-values/validators",
+ "type": "library",
+ "description": "Common ValueValidator implementations",
+ "keywords": [
+ "datavalues",
+ "wikidata",
+ "validators",
+ "validation"
+ ],
+ "homepage": "https://github.com/DataValues/Validators",
+ "license": "GPL-2.0-or-later",
+ "authors": [
+ {
+ "name": "Jeroen De Dauw",
+ "email": "jeroendedauw@gmail.com",
+ "homepage": "http://jeroendedauw.com",
+ "role": "Developer"
+ },
+ {
+ "name": "The Wikidata team",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.net/wikidata"
+ },
+ "require": {
+ "php": ">=5.5.9",
+ "data-values/data-values": "^2.1.1|~1.0|~0.1",
+ "data-values/interfaces": "~0.2.0|~0.1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35",
+ "wikibase/wikibase-codesniffer": "0.4.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "ValueValidators\\": "src"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.1.x-dev"
+ }
+ },
+ "scripts": {
+ "test": [
+ "composer validate --no-interaction",
+ "phpcs -p -s",
+ "phpunit"
+ ]
+ }
+}
diff --git a/www/wiki/vendor/data-values/validators/phpunit.xml.dist b/www/wiki/vendor/data-values/validators/phpunit.xml.dist
new file mode 100644
index 00000000..7978f7e0
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/phpunit.xml.dist
@@ -0,0 +1,25 @@
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ bootstrap="tests/bootstrap.php"
+ cacheTokens="false"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ stopOnError="false"
+ stopOnFailure="false"
+ stopOnIncomplete="false"
+ stopOnSkipped="false"
+ strict="true"
+ verbose="true">
+ <testsuites>
+ <testsuite name="DataValuesValidators">
+ <directory>tests</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist addUncoveredFilesFromWhitelist="true">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/www/wiki/vendor/data-values/validators/src/DimensionValidator.php b/www/wiki/vendor/data-values/validators/src/DimensionValidator.php
new file mode 100644
index 00000000..9d7c3ac6
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/DimensionValidator.php
@@ -0,0 +1,267 @@
+<?php
+
+namespace ValueValidators;
+
+use Exception;
+
+/**
+ * ValueValidator that validates a dimension value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class DimensionValidator extends ValueValidatorObject {
+
+ /**
+ * @since 0.1
+ *
+ * @var boolean
+ */
+ protected $allowAuto = false;
+
+ /**
+ * @since 0.1
+ *
+ * @var array
+ */
+ protected $allowedUnits = array( 'px', '' );
+
+ /**
+ * @since 0.1
+ *
+ * @var integer
+ */
+ protected $minPercentage = 0;
+
+ /**
+ * @since 0.1
+ *
+ * @var integer
+ */
+ protected $maxPercentage = 100;
+
+ /**
+ * @since 0.1
+ *
+ * @var string
+ */
+ protected $defaultUnit = 'px';
+
+ /**
+ * Lower bound of the range (included). Either a number or false, for no lower limit.
+ *
+ * @since 0.1
+ *
+ * @var false|int|float
+ */
+ protected $lowerBound = false;
+
+ /**
+ * Upper bound of the range (included). Either a number or false, for no upper limit.
+ *
+ * @since 0.1
+ *
+ * @var false|int|float
+ */
+ protected $upperBound = false;
+
+ /**
+ * Sets the lower bound (included).
+ *
+ * @since 0.1
+ *
+ * @param $lowerBound false|int|float
+ */
+ public function setLowerBound( $lowerBound ) {
+ $this->lowerBound = $lowerBound;
+ }
+
+ /**
+ * Sets the upper bound (included).
+ *
+ * @since 0.1
+ *
+ * @param $upperBound false|int|float
+ */
+ public function setUpperBound( $upperBound ) {
+ $this->upperBound = $upperBound;
+ }
+
+ /**
+ * Requires the value to be in the specified range.
+ *
+ * @since 0.1
+ *
+ * @param $lowerBound false|int|float
+ * @param $upperBound false|int|float
+ */
+ public function setRange( $lowerBound, $upperBound ) {
+ $this->lowerBound = $lowerBound;
+ $this->upperBound = $upperBound;
+ }
+
+ /**
+ * @see ValueValidatorObject::doValidation
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ */
+ public function doValidation( $value ) {
+ if ( !is_string( $value ) && !is_int( $value ) && !is_float( $value ) ) {
+ $this->addErrorMessage( 'Dimension is not a string, float or int' );
+ return;
+ }
+
+ if ( !is_string( $value ) ) {
+ $value = (string)$value;
+ }
+
+ if ( $value === 'auto' ) {
+ if ( !$this->allowAuto ) {
+ $this->addErrorMessage( 'Dimension value cannot be auto' );
+ }
+ return;
+ }
+
+ if ( !preg_match( '/^\d+(\.\d+)?(' . implode( '|', $this->allowedUnits ) . ')\z/', $value ) ) {
+ $this->addErrorMessage( 'Not a valid dimension value' );
+ return;
+ }
+
+ if ( strpos( $value, '%' ) !== false ) {
+ $upperBound = $this->maxPercentage;
+ $lowerBound = $this->minPercentage;
+ } else {
+ $upperBound = $this->upperBound;
+ $lowerBound = $this->lowerBound;
+ }
+
+ $value = (float)preg_replace( '/\D+/', '', $value );
+
+ $rangeValidator = new RangeValidator();
+ $rangeValidator->setRange( $lowerBound, $upperBound );
+
+ $this->runSubValidator( $value, $rangeValidator );
+ }
+
+ /**
+ * If 'auto' should be seen as a valid value.
+ *
+ * @since 0.1
+ *
+ * @param boolean $allowAuto
+ */
+ public function setAllowAuto( $allowAuto ) {
+ $this->allowAuto = $allowAuto;
+ }
+
+ /**
+ * Set the upper bound for the value in case it's a percentage.
+ *
+ * @since 0.1
+ *
+ * @param integer $maxPercentage
+ */
+ public function setMaxPercentage( $maxPercentage ) {
+ $this->maxPercentage = $maxPercentage;
+ }
+
+ /**
+ * Set the lower bound for the value in case it's a percentage.
+ *
+ * @since 0.1
+ *
+ * @param integer $minPercentage
+ */
+ public function setMinPercentage( $minPercentage ) {
+ $this->minPercentage = $minPercentage;
+ }
+
+ /**
+ * Sets the default unit, ie the one that will be assumed when the empty unit is provided.
+ *
+ * @since 0.1
+ *
+ * @param string $defaultUnit
+ */
+ public function setDefaultUnit( $defaultUnit ) {
+ $this->defaultUnit = $defaultUnit;
+ }
+
+ /**
+ * Sets the allowed units.
+ *
+ * @since 0.1
+ *
+ * @param array $units
+ */
+ public function setAllowedUnits( array $units = array( 'px', 'em', 'ex', '%', '' ) ) {
+ $this->allowedUnits = $units;
+ }
+
+ /**
+ * Returns the allowed units.
+ *
+ * @since 0.1
+ *
+ * @return string[]
+ */
+ public function getAllowedUnits() {
+ return $this->allowedUnits;
+ }
+
+ /**
+ * Returns the default unit.
+ *
+ * @since 0.1
+ *
+ * @return string
+ */
+ public function getDefaultUnit() {
+ return $this->defaultUnit;
+ }
+
+ /**
+ * @see ValueValidator::setOptions
+ *
+ * @since 0.1
+ *
+ * @param array $options
+ * @throws Exception
+ */
+ public function setOptions( array $options ) {
+ parent::setOptions( $options );
+
+ if ( array_key_exists( 'allowauto', $options ) ) {
+ $this->setAllowAuto( $options['allowauto'] );
+ }
+
+ if ( array_key_exists( 'maxpercentage', $options ) ) {
+ $this->setMaxPercentage( $options['maxpercentage'] );
+ }
+
+ if ( array_key_exists( 'minpercentage', $options ) ) {
+ $this->setMinPercentage( $options['minpercentage'] );
+ }
+
+ if ( array_key_exists( 'units', $options ) ) {
+ $this->setAllowedUnits( $options['units'] );
+ }
+
+ if ( array_key_exists( 'defaultunit', $options ) ) {
+ $this->setDefaultUnit( $options['defaultunit'] );
+ }
+
+ if ( array_key_exists( 'lowerbound', $options ) ) {
+ $this->setLowerBound( $options['lowerbound'] );
+ }
+
+ if ( array_key_exists( 'upperbound', $options ) ) {
+ $this->setUpperBound( $options['upperbound'] );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/src/ListValidator.php b/www/wiki/vendor/data-values/validators/src/ListValidator.php
new file mode 100644
index 00000000..fde8d776
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/ListValidator.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace ValueValidators;
+
+use Exception;
+
+/**
+ * ValueValidator that validates a list of values.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Thiemo Kreuz
+ */
+class ListValidator extends ValueValidatorObject {
+
+ /**
+ * @see ValueValidatorObject::doValidation
+ *
+ * @since 0.1
+ *
+ * @param array $value
+ *
+ * @throws Exception
+ */
+ public function doValidation( $value ) {
+ if ( !is_array( $value ) ) {
+ $this->addErrorMessage( 'Not an array' );
+ return;
+ }
+
+ $options = array();
+
+ if ( array_key_exists( 'elementcount', $this->options ) ) {
+ $options['range'] = $this->options['elementcount'];
+ }
+
+ if ( array_key_exists( 'minelements', $this->options ) ) {
+ $options['lowerbound'] = $this->options['minelements'];
+ }
+
+ if ( array_key_exists( 'maxelements', $this->options ) ) {
+ $options['upperbound'] = $this->options['maxelements'];
+ }
+
+ $validator = new RangeValidator();
+ $validator->setOptions( $options );
+ $this->runSubValidator( count( $value ), $validator, 'length' );
+ }
+
+ /**
+ * @see ValueValidatorObject::enableWhitelistRestrictions
+ *
+ * @since 0.1
+ *
+ * @return bool
+ */
+ protected function enableWhitelistRestrictions() {
+ return false;
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/src/NullValidator.php b/www/wiki/vendor/data-values/validators/src/NullValidator.php
new file mode 100644
index 00000000..514775e8
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/NullValidator.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace ValueValidators;
+
+/**
+ * ValueValidator does a null validation (ie everything passes).
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ *
+ * @codeCoverageIgnore
+ */
+class NullValidator implements ValueValidator {
+
+ /**
+ * @see ValueValidator::validate
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ *
+ * @return Result Always successfull.
+ */
+ public function validate( $value ) {
+ return Result::newSuccess();
+ }
+
+ /**
+ * @see ValueValidator::setOptions
+ *
+ * @since 0.1
+ *
+ * @param array $options
+ */
+ public function setOptions( array $options ) {
+ // No op
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/src/RangeValidator.php b/www/wiki/vendor/data-values/validators/src/RangeValidator.php
new file mode 100644
index 00000000..2166ad67
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/RangeValidator.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace ValueValidators;
+
+use Exception;
+
+/**
+ * ValueValidator that validates if a numeric value is within a certain range.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class RangeValidator extends ValueValidatorObject {
+
+ /**
+ * Lower bound of the range (included). Either a number or false, for no lower limit.
+ *
+ * @since 0.1
+ *
+ * @var false|int|float
+ */
+ protected $lowerBound = false;
+
+ /**
+ * Upper bound of the range (included). Either a number or false, for no upper limit.
+ *
+ * @since 0.1
+ *
+ * @var false|int|float
+ */
+ protected $upperBound = false;
+
+ /**
+ * Sets the lower bound (included).
+ *
+ * @since 0.1
+ *
+ * @param $lowerBound false|int|float
+ */
+ public function setLowerBound( $lowerBound ) {
+ $this->lowerBound = $lowerBound;
+ }
+
+ /**
+ * Sets the upper bound (included).
+ *
+ * @since 0.1
+ *
+ * @param $upperBound false|int|float
+ */
+ public function setUpperBound( $upperBound ) {
+ $this->upperBound = $upperBound;
+ }
+
+ /**
+ * Requires the value to be in the specified range.
+ *
+ * @since 0.1
+ *
+ * @param $lowerBound false|int|float
+ * @param $upperBound false|int|float
+ */
+ public function setRange( $lowerBound, $upperBound ) {
+ $this->lowerBound = $lowerBound;
+ $this->upperBound = $upperBound;
+ }
+
+ /**
+ * Requires the value to be within the range of a point.
+ * Bounds are included, ie 6 will be valid for point 4 within range 2.
+ *
+ * @since 0.1
+ *
+ * @param int|float $point
+ * @param int|float $range
+ */
+ public function setWithinRange( $point, $range ) {
+ $this->lowerBound = $point - $range;
+ $this->upperBound = $point + $range;
+ }
+
+ /**
+ * @see ValueValidatorObject::doValidation
+ *
+ * @since 0.1
+ *
+ * @param mixed $value
+ */
+ public function doValidation( $value ) {
+ if ( !true ) {
+ // TODO: type check
+ $this->addErrorMessage( 'Not a numeric value - cannot check the range' );
+ return;
+ }
+
+ $this->validateBounds( $value );
+ }
+
+ /**
+ * Validates the parameters value and returns the result.
+ *
+ * @since 0.1
+ *
+ * @param $value mixed
+ * @param float|null|false $upperBound
+ * @param float|null|false $lowerBound
+ *
+ * @return boolean
+ */
+ protected function validateBounds( $value, $upperBound = null, $lowerBound = null ) {
+ $upperBound = is_null( $upperBound ) ? $this->upperBound : $upperBound;
+ $lowerBound = is_null( $lowerBound ) ? $this->lowerBound : $lowerBound;
+
+ $smallEnough = $upperBound === false || $value <= $upperBound;
+ $bigEnough = $lowerBound === false || $value >= $lowerBound;
+
+ if ( !$smallEnough ) {
+ $this->addErrorMessage( 'Value exceeding upper bound' );
+ }
+
+ if ( !$bigEnough ) {
+ $this->addErrorMessage( 'Value exceeding lower bound' );
+ }
+
+ return $smallEnough && $bigEnough;
+ }
+
+ /**
+ * @see ValueValidator::setOptions
+ *
+ * @since 0.1
+ *
+ * @param array $options
+ * @throws Exception
+ */
+ public function setOptions( array $options ) {
+ parent::setOptions( $options );
+
+ if ( array_key_exists( 'range', $options ) ) {
+ if ( is_array( $options['range'] ) && count( $options['range'] ) == 2 ) {
+ $this->setRange( $options['range'][0], $options['range'][1] );
+ } else {
+ throw new Exception( 'The range argument must be an array with two elements' );
+ }
+ }
+
+ if ( array_key_exists( 'withinrange', $options ) ) {
+ if ( is_array( $options['withinrange'] ) && count( $options['withinrange'] ) == 2 ) {
+ $this->setWithinRange( $options['withinrange'][0], $options['withinrange'][1] );
+ } else {
+ throw new Exception( 'The withinrange argument must be an array with two elements' );
+ }
+ }
+
+ if ( array_key_exists( 'lowerbound', $options ) ) {
+ $this->setLowerBound( $options['lowerbound'] );
+ }
+
+ if ( array_key_exists( 'upperbound', $options ) ) {
+ $this->setUpperBound( $options['upperbound'] );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/src/StringValidator.php b/www/wiki/vendor/data-values/validators/src/StringValidator.php
new file mode 100644
index 00000000..37304ea0
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/StringValidator.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace ValueValidators;
+
+use Exception;
+
+/**
+ * ValueValidator that validates a string value.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class StringValidator extends ValueValidatorObject {
+
+ /**
+ * @see ValueValidatorObject::doValidation
+ *
+ * @since 0.1
+ *
+ * @param string $value
+ *
+ * @throws Exception
+ */
+ public function doValidation( $value ) {
+ if ( !is_string( $value ) ) {
+ $this->addErrorMessage( 'Not a string' ); // TODO
+ return;
+ }
+
+ $lowerBound = false;
+ $upperBound = false;
+
+ if ( array_key_exists( 'length', $this->options ) ) {
+ $lowerBound = $this->options['length'];
+ $upperBound = $this->options['length'];
+ } else {
+ if ( array_key_exists( 'minlength', $this->options ) ) {
+ $lowerBound = $this->options['minlength'];
+ }
+
+ if ( array_key_exists( 'maxlength', $this->options ) ) {
+ $upperBound = $this->options['maxlength'];
+ }
+ }
+
+ if ( $lowerBound !== false || $upperBound !== false ) {
+ $rangeValidator = new RangeValidator();
+ $rangeValidator->setRange( $lowerBound, $upperBound );
+ $this->runSubValidator( strlen( $value ), $rangeValidator, 'length' );
+ }
+
+ if ( array_key_exists( 'regex', $this->options ) ) {
+ $match = preg_match( $this->options['regex'], $value );
+
+ if ( $match === false ) {
+ throw new Exception( 'The regex argument must be a valid Perl regular expression.' );
+ } elseif ( $match === 0 ) {
+ $this->addErrorMessage( 'String does not match the regular expression ' . $this->options['regex'] );
+ }
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/src/TitleValidator.php b/www/wiki/vendor/data-values/validators/src/TitleValidator.php
new file mode 100644
index 00000000..3459d68d
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/src/TitleValidator.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace ValueValidators;
+
+use Title;
+
+/**
+ * ValueValidator that validates a Title object.
+ *
+ * @since 0.1
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class TitleValidator extends ValueValidatorObject {
+
+ /**
+ * @since 0.1
+ *
+ * @var bool
+ */
+ protected $hasToExist = true;
+
+ /**
+ * @since 0.1
+ *
+ * @param bool $hasToExist
+ */
+ public function setHasToExist( $hasToExist ) {
+ $this->hasToExist = $hasToExist;
+ }
+
+ /**
+ * @see ValueValidatorObject::doValidation
+ *
+ * @since 0.1
+ *
+ * @param Title $value
+ */
+ public function doValidation( $value ) {
+ if ( !( $value instanceof Title ) ) {
+ $this->addErrorMessage( 'Not a title' );
+ } elseif ( $this->hasToExist && !$value->exists() ) {
+ $this->addErrorMessage( 'Title does not exist' );
+ }
+ }
+
+ /**
+ * @see ValueValidator::setOptions
+ *
+ * @since 0.1
+ *
+ * @param array $options
+ */
+ public function setOptions( array $options ) {
+ parent::setOptions( $options );
+
+ if ( array_key_exists( 'hastoexist', $options ) ) {
+ $this->setHasToExist( $options['hastoexist'] );
+ }
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php
new file mode 100644
index 00000000..7254ddd0
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/DimensionValidatorTest.php
@@ -0,0 +1,108 @@
+<?php
+
+namespace ValueValidators\Tests;
+
+use PHPUnit\Framework\TestCase;
+use ValueValidators\DimensionValidator;
+
+/**
+ * @covers ValueValidators\DimensionValidator
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class DimensionValidatorTest extends TestCase {
+
+ /**
+ * @var DimensionValidator
+ */
+ private $validator;
+
+ protected function setUp() {
+ $this->validator = new DimensionValidator();
+ }
+
+ public function testWhenAutoIsNotAllowed_autoIsNotValid() {
+ $this->validator->setAllowAuto( false );
+ $this->assertIsNotValid( 'auto' );
+ }
+
+ private function assertIsNotValid( $value ) {
+ $this->assertFalse( $this->validator->validate( $value )->isValid() );
+ }
+
+ public function testWhenAutoIsAllowed_autoIsValid() {
+ $this->validator->setAllowAuto( true );
+ $this->assertIsValid( 'auto' );
+ }
+
+ private function assertIsValid( $value ) {
+ $this->assertTrue( $this->validator->validate( $value )->isValid() );
+ }
+
+ public function testUsingDefaultSettings_pxIsAllowed() {
+ $this->assertIsValid( '100px' );
+ }
+
+ public function testUsingDefaultSettings_NoUnitIsAllowed() {
+ $this->assertIsValid( '100' );
+ }
+
+ public function testUsingDefaultSettings_trailingNewlineIsInvalid() {
+ $this->assertIsNotValid( "100\n" );
+ }
+
+ public function testGivenUpperBound_valueUnderIsValid() {
+ $this->validator->setUpperBound( 100 );
+ $this->assertIsValid( '99' );
+ }
+
+ public function testGivenUpperBound_valueEqualIsValid() {
+ $this->validator->setUpperBound( 100 );
+ $this->assertIsValid( '100' );
+ }
+
+ public function testGivenUpperBound_valueOverIsInvalid() {
+ $this->validator->setUpperBound( 100 );
+ $this->assertIsNotValid( '101' );
+ }
+
+ public function testUsingDefaultSettings_percentageIsNotValid() {
+ $this->assertIsNotValid( '50%' );
+ }
+
+ public function testWhenPercentageInUnitList_percentageValid() {
+ $this->validator->setAllowedUnits( array( 'px', '%' ) );
+ $this->assertIsValid( '50%' );
+ }
+
+ public function testGivenLowerPercentageBound_valueOverIsValid() {
+ $this->validator->setAllowedUnits( array( '%' ) );
+ $this->validator->setMinPercentage( 50 );
+ $this->assertIsValid( '51%' );
+ }
+
+ public function testGivenLowerPercentageBound_valueEqualIsValid() {
+ $this->validator->setAllowedUnits( array( '%' ) );
+ $this->validator->setMinPercentage( 50 );
+ $this->assertIsValid( '50%' );
+ }
+
+ public function testGivenLowerPercentageBound_valueUnderIsNotValid() {
+ $this->validator->setAllowedUnits( array( '%' ) );
+ $this->validator->setMinPercentage( 50 );
+ $this->assertIsNotValid( '49%' );
+ }
+
+ public function testInvalidValuesAreInvalid() {
+ $this->assertIsNotValid( '' );
+ $this->assertIsNotValid( 'a' );
+ $this->assertIsNotValid( '1a' );
+ $this->assertIsNotValid( '1px2' );
+ $this->assertIsNotValid( 'a1px' );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php
new file mode 100644
index 00000000..5a07f07f
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/ListValidatorTest.php
@@ -0,0 +1,220 @@
+<?php
+
+namespace ValueValidators\Tests;
+
+use PHPUnit\Framework\TestCase;
+use ValueValidators\Error;
+use ValueValidators\ListValidator;
+
+/**
+ * @covers ValueValidators\ListValidator
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0-or-later
+ * @author Thiemo Kreuz
+ */
+class ListValidatorTest extends TestCase {
+
+ /**
+ * @dataProvider invalidRangeProvider
+ */
+ public function testInvalidRange( $range ) {
+ $validator = new ListValidator();
+ $validator->setOptions( [ 'elementcount' => $range ] );
+ $this->setExpectedException( 'Exception' );
+ $validator->validate( [] );
+ }
+
+ public function invalidRangeProvider() {
+ return [
+ [ null ],
+ [ 0 ],
+ [ '' ],
+ [ [] ],
+ [ [ 0 ] ],
+ [ [ 0, 0, 0 ] ],
+ ];
+ }
+
+ /**
+ * @dataProvider valueProvider
+ */
+ public function testValidate( $value, array $options, $expectedErrors ) {
+ $validator = new ListValidator();
+ $validator->setOptions( $options );
+ $result = $validator->validate( $value );
+
+ if ( !is_array( $expectedErrors ) ) {
+ $expectedErrors = [ $expectedErrors ];
+ }
+
+ $this->assertEquals( $expectedErrors, $result->getErrors() );
+ }
+
+ public function valueProvider() {
+ return [
+ [
+ 'value' => null,
+ 'options' => [],
+ 'expectedErrors' => Error::newError( 'Not an array' )
+ ],
+ [
+ 'value' => 0,
+ 'options' => [],
+ 'expectedErrors' => Error::newError( 'Not an array' )
+ ],
+ [
+ 'value' => '',
+ 'options' => [],
+ 'expectedErrors' => Error::newError( 'Not an array' )
+ ],
+ [
+ 'value' => [],
+ 'options' => [],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [],
+ 'expectedErrors' => []
+ ],
+
+ // Lower bound only
+ [
+ 'value' => [],
+ 'options' => [ 'minelements' => null ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'minelements' => 0 ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'minelements' => 1 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' )
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'minelements' => 1 ],
+ 'expectedErrors' => []
+ ],
+
+ // Upper bound only
+ [
+ 'value' => [],
+ 'options' => [ 'maxelements' => null ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'maxelements' => 0 ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'maxelements' => 0 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' )
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'maxelements' => 1 ],
+ 'expectedErrors' => []
+ ],
+
+ // Lower and upper bound
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 0, 0 ] ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'elementcount' => [ 2, 2 ] ],
+ 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' )
+ ],
+ [
+ 'value' => [ 1, 2 ],
+ 'options' => [ 'elementcount' => [ 2, 2 ] ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'elementcount' => [ 0, 0 ] ],
+ 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' )
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 0, 0 ] ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 2, 0 ] ],
+ 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' )
+ ],
+ [
+ 'value' => [ 1, 2 ],
+ 'options' => [ 'elementcount' => [ 2, 0 ] ],
+ 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' )
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'elementcount' => [ 2, 0 ] ],
+ 'expectedErrors' => [
+ Error::newError( 'Value exceeding upper bound', 'length' ),
+ Error::newError( 'Value exceeding lower bound', 'length' ),
+ ]
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'minelements' => 2, 'maxelements' => 0 ],
+ 'expectedErrors' => [
+ Error::newError( 'Value exceeding upper bound', 'length' ),
+ Error::newError( 'Value exceeding lower bound', 'length' ),
+ ]
+ ],
+
+ // Conflicting options
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => null ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => false ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'elementcount' => [ 1, 1 ], 'minelements' => 0 ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [],
+ 'options' => [ 'minelements' => 0, 'elementcount' => [ 1, 1 ] ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'elementcount' => [ 0, 0 ], 'maxelements' => false ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'elementcount' => [ 0, 0 ], 'maxelements' => 1 ],
+ 'expectedErrors' => []
+ ],
+ [
+ 'value' => [ 1 ],
+ 'options' => [ 'maxelements' => 1, 'elementcount' => [ 0, 0 ] ],
+ 'expectedErrors' => []
+ ],
+ ];
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php
new file mode 100644
index 00000000..c2301fec
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/RangeValidatorTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace ValueValidators\Tests;
+
+use PHPUnit\Framework\TestCase;
+use ValueValidators\RangeValidator;
+
+/**
+ * @covers ValueValidators\RangeValidator
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0-or-later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class RangeValidatorTest extends TestCase {
+
+ /**
+ * @dataProvider withinBoundsProvider
+ */
+ public function testNumberWithinRange_WhenSetWithSetRange( $number, $lowerBound, $upperBound ) {
+ $rangeValidator = new RangeValidator();
+ $rangeValidator->setRange( $lowerBound, $upperBound );
+
+ $this->assertTrue( $rangeValidator->validate( $number )->isValid() );
+ }
+
+ public function withinBoundsProvider() {
+ return array(
+ array( 0, 0, 0 ),
+ array( 5, 0, 9 ),
+ array( -5, -9, 0 ),
+ array( 0, -5, 5 ),
+ );
+ }
+
+ /**
+ * @dataProvider withinBoundsProvider
+ */
+ public function testNumberWithinRange_WhenSetWithIndividualSetters( $number, $lowerBound, $upperBound ) {
+ $rangeValidator = new RangeValidator();
+ $rangeValidator->setLowerBound( $lowerBound );
+ $rangeValidator->setUpperBound( $upperBound );
+
+ $this->assertTrue( $rangeValidator->validate( $number )->isValid() );
+ }
+
+ /**
+ * @dataProvider outsideBoundsProvider
+ */
+ public function testNumberOutsideRange_WhenSetWithSetRange( $number, $lowerBound, $upperBound ) {
+ $rangeValidator = new RangeValidator();
+ $rangeValidator->setRange( $lowerBound, $upperBound );
+
+ $this->assertFalse( $rangeValidator->validate( $number )->isValid() );
+ }
+
+ public function outsideBoundsProvider() {
+ return array(
+ array( 0, 1, 1 ),
+ array( -1, 0, 9 ),
+ array( 100, -200, 99 ),
+ array( -42, -41, 99 ),
+ );
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php
new file mode 100644
index 00000000..a2d2fe2e
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/StringValidatorTest.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace ValueValidators\Tests;
+
+use PHPUnit\Framework\TestCase;
+use ValueValidators\Error;
+use ValueValidators\StringValidator;
+
+/**
+ * @covers ValueValidators\StringValidator
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0-or-later
+ * @author Thiemo Kreuz
+ */
+class StringValidatorTest extends TestCase {
+
+ /**
+ * @dataProvider stringProvider
+ */
+ public function testValidate( $value, array $options, $expectedError ) {
+ $validator = new StringValidator();
+ $validator->setOptions( $options );
+ $result = $validator->validate( $value );
+
+ $this->assertEquals(
+ $expectedError === null ? [] : [ $expectedError ],
+ $result->getErrors()
+ );
+ }
+
+ public function stringProvider() {
+ return [
+ [
+ 'value' => null,
+ 'options' => [],
+ 'expectedErrors' => Error::newError( 'Not a string' )
+ ],
+ [
+ 'value' => '',
+ 'options' => [],
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => '',
+ 'options' => [ 'length' => 1 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' )
+ ],
+ [
+ 'value' => '1',
+ 'options' => [ 'length' => 1 ],
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => '1',
+ 'options' => [ 'length' => 0 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' )
+ ],
+ [
+ 'value' => '',
+ 'options' => [ 'length' => 0 ],
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => '',
+ 'options' => [ 'minlength' => 1 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding lower bound', 'length' )
+ ],
+ [
+ 'value' => '1',
+ 'options' => [ 'minlength' => 1 ],
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => '1',
+ 'options' => [ 'maxlength' => 0 ],
+ 'expectedErrors' => Error::newError( 'Value exceeding upper bound', 'length' )
+ ],
+ [
+ 'value' => '',
+ 'options' => [ 'maxlength' => 0 ],
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => '1',
+ 'options' => [ 'regex' => '/^$/' ],
+ 'expectedErrors' => Error::newError( 'String does not match the regular expression /^$/' )
+ ],
+ [
+ 'value' => '',
+ 'options' => [ 'regex' => '/^$/' ],
+ 'expectedErrors' => null
+ ],
+ ];
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php b/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php
new file mode 100644
index 00000000..24c21c17
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/ValueValidators/TitleValidatorTest.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace ValueValidators\Tests;
+
+use PHPUnit\Framework\TestCase;
+use ValueValidators\Error;
+use ValueValidators\TitleValidator;
+
+/**
+ * @covers ValueValidators\TitleValidator
+ *
+ * @group ValueValidators
+ * @group DataValueExtensions
+ *
+ * @license GPL-2.0-or-later
+ * @author Thiemo Kreuz
+ */
+class TitleValidatorTest extends TestCase {
+
+ /**
+ * @dataProvider titleProvider
+ */
+ public function testValidate( $value, $hasToExist, $expectedError ) {
+ $validator = new TitleValidator();
+ $validator->setOptions( [ 'hastoexist' => $hasToExist ] );
+ $result = $validator->validate( $value );
+
+ $this->assertEquals(
+ $expectedError === null ? [] : [ $expectedError ],
+ $result->getErrors()
+ );
+ }
+
+ public function titleProvider() {
+ $title = $this->getMockBuilder( 'Title' )
+ ->disableOriginalConstructor()
+ ->setMethods( [ 'exists' ] )
+ ->getMock();
+ $title->expects( $this->any() )
+ ->method( 'exists' )
+ ->will( $this->returnValue( false ) );
+
+ return [
+ [
+ 'value' => null,
+ 'hasToExist' => false,
+ 'expectedErrors' => Error::newError( 'Not a title' )
+ ],
+ [
+ 'value' => $title,
+ 'hasToExist' => false,
+ 'expectedErrors' => null
+ ],
+ [
+ 'value' => $title,
+ 'hasToExist' => true,
+ 'expectedErrors' => Error::newError( 'Title does not exist' )
+ ],
+ ];
+ }
+
+}
diff --git a/www/wiki/vendor/data-values/validators/tests/bootstrap.php b/www/wiki/vendor/data-values/validators/tests/bootstrap.php
new file mode 100644
index 00000000..ac82d460
--- /dev/null
+++ b/www/wiki/vendor/data-values/validators/tests/bootstrap.php
@@ -0,0 +1,14 @@
+<?php
+
+if ( PHP_SAPI !== 'cli' ) {
+ die( 'Not an entry point' );
+}
+
+error_reporting( E_ALL | E_STRICT );
+ini_set( 'display_errors', 1 );
+
+if ( !is_readable( __DIR__ . '/../vendor/autoload.php' ) ) {
+ die( 'You need to install this package with Composer before you can run the tests' );
+}
+
+require_once __DIR__ . '/../vendor/autoload.php';